Major restructure: Remove Confluence, add V2 data structure, organize for dev/prod

- Import real data from PDF (35 Bambu Lab filaments)
- Remove all Confluence integration and dependencies
- Implement new V2 data structure with proper inventory tracking
- Add backwards compatibility for existing data
- Create enhanced UI components (ColorSwatch, InventoryBadge, MaterialBadge)
- Add advanced filtering with quick filters and multi-criteria search
- Organize codebase for dev/prod environments
- Update Lambda functions to support both V1/V2 formats
- Add inventory summary dashboard
- Clean up project structure and documentation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
DaX
2025-06-20 01:12:50 +02:00
parent a2252fa923
commit 18110ab159
40 changed files with 2171 additions and 1094 deletions

View File

@@ -0,0 +1,29 @@
import { readFileSync, existsSync } from 'fs';
import { join } from 'path';
describe('No Mock Data Tests', () => {
it('should not have data.json in public folder', () => {
const dataJsonPath = join(process.cwd(), 'public', 'data.json');
expect(existsSync(dataJsonPath)).toBe(false);
});
it('should not have fallback to data.json in page.tsx', () => {
const pagePath = join(process.cwd(), 'app', 'page.tsx');
const pageContent = readFileSync(pagePath, 'utf-8');
expect(pageContent).not.toContain('data.json');
expect(pageContent).not.toContain("'/data.json'");
expect(pageContent).toContain('API URL not configured');
});
it('should use NEXT_PUBLIC_API_URL in all components', () => {
const pagePath = join(process.cwd(), 'app', 'page.tsx');
const adminPath = join(process.cwd(), 'app', 'admin', 'dashboard', 'page.tsx');
const pageContent = readFileSync(pagePath, 'utf-8');
const adminContent = readFileSync(adminPath, 'utf-8');
expect(pageContent).toContain('process.env.NEXT_PUBLIC_API_URL');
expect(adminContent).toContain('process.env.NEXT_PUBLIC_API_URL');
});
});

View File

@@ -1,65 +0,0 @@
// Mock Next.js server components
jest.mock('next/server', () => ({
NextResponse: {
json: (data: any, init?: ResponseInit) => ({
json: async () => data,
...init
})
}
}));
// Mock confluence module
jest.mock('../src/server/confluence', () => ({
fetchFromConfluence: jest.fn()
}));
import { GET } from '../app/api/filaments/route';
import { fetchFromConfluence } from '../src/server/confluence';
describe('API Security Tests', () => {
const originalEnv = process.env;
beforeEach(() => {
jest.resetModules();
process.env = { ...originalEnv };
});
afterEach(() => {
process.env = originalEnv;
});
it('should not expose credentials in error responses', async () => {
// Simulate missing environment variables
delete process.env.CONFLUENCE_TOKEN;
const response = await GET();
const data = await response.json();
// Check that response doesn't contain sensitive information
expect(JSON.stringify(data)).not.toContain('ATATT');
expect(JSON.stringify(data)).not.toContain('token');
expect(JSON.stringify(data)).not.toContain('password');
expect(data.error).toBe('Server configuration error');
});
it('should not expose internal error details', async () => {
// Set valid environment
process.env.CONFLUENCE_API_URL = 'https://test.atlassian.net';
process.env.CONFLUENCE_TOKEN = 'test-token';
process.env.CONFLUENCE_PAGE_ID = 'test-page';
// Mock fetchFromConfluence to throw an error
const mockFetchFromConfluence = fetchFromConfluence as jest.MockedFunction<typeof fetchFromConfluence>;
mockFetchFromConfluence.mockRejectedValueOnce(new Error('Internal database error with sensitive details'));
const response = await GET();
const data = await response.json();
// Should get generic error, not specific details
expect(data.error).toBe('Failed to fetch filaments');
expect(data).not.toHaveProperty('stack');
expect(data).not.toHaveProperty('message');
expect(JSON.stringify(data)).not.toContain('Internal database error');
expect(JSON.stringify(data)).not.toContain('sensitive details');
});
});