Audit Date: March 6, 2026
Auditor: Award-Winning Architecture & Interior Design Technology Audit
Codebase Version: Branch docs/userflow-and-testing-guide (commit 3db04ff)
Scope: Full-stack audit -- 407 source files, ~82,746 lines of code across 11 microservices, 5 ML pipelines, 5 shared packages, 1 Next.js frontend, Kubernetes/Terraform infrastructure, and CI/CD pipelines.
Part 1: Code & Infrastructure Audit
- Executive Summary
- Architecture Overview & Assessment
- Security Audit
- Frontend Audit (Next.js Web App)
- Backend Audit (Python Microservices)
- ML Pipeline Audit
- Database & Schema Audit
- Infrastructure & DevOps Audit
- CI/CD Pipeline Audit
- Testing Coverage Audit
- Code Quality Metrics
- OWASP Top 10 Compliance
- Prioritized Remediation Roadmap
- Appendix: Full Finding Index
Part 2: Missing Features, Errors, UI/UX Issues & Desired Features
- Requirements vs. Implementation Gap Analysis
- UI/UX Issues & Desired Changes
- Backend API Errors & Incomplete Implementations
- Desired Features & Enhancement Roadmap
- Consolidated Priority Matrix
- Final Consolidated Metrics
OpenLintel is an AI-powered interior design and architecture platform built as a monorepo with:
| Layer | Technology | Components |
|---|---|---|
| Frontend | Next.js 15, React 19, TailwindCSS, tRPC, Three.js | 1 web app |
| Backend | FastAPI, Python 3.12, SQLAlchemy 2.0, LangGraph | 11 microservices |
| ML/AI | SAM2, DepthAnythingV2, LiteLLM, CLIP, Meilisearch | 5 ML pipelines |
| Data | PostgreSQL 16, Redis 7, MinIO, Meilisearch | 4 data stores |
| Infra | Kubernetes (EKS), Terraform, Docker, GitHub Actions | Full IaC |
+-------------------------------------------------------------------+
| OVERALL HEALTH: 52 / 100 |
+-------------------------------------------------------------------+
| Security [####------] 38/100 -- NEEDS IMMEDIATE WORK |
| Code Quality [######----] 62/100 -- MODERATE |
| Architecture [#######---] 71/100 -- GOOD FOUNDATION |
| Performance [#####-----] 48/100 -- NEEDS ATTENTION |
| Testing [##--------] 15/100 -- CRITICALLY LOW |
| Infrastructure [#####-----] 45/100 -- SIGNIFICANT GAPS |
| Documentation [######----] 60/100 -- ADEQUATE |
| Accessibility [###-------] 30/100 -- POOR |
+-------------------------------------------------------------------+
| Severity | Count | Breakdown |
|---|---|---|
| CRITICAL | 7 | 4 secrets/credentials, 3 K8s security |
| HIGH | 31 | Security (8), Code Quality (6), Performance (5), Architecture (5), Testing (4), Infra (3) |
| MEDIUM | 48 | Spread across all categories |
| LOW | 18 | Code quality, documentation, minor improvements |
| TOTAL | 104 |
- Hardcoded secrets in version control -- K8s secrets.yaml, docker-compose.yml contain plaintext/base64 credentials (CRITICAL)
- Stripe webhook signature bypass -- Empty
STRIPE_WEBHOOK_SECRETskips verification, allowing unauthorized payment injection (HIGH) - Missing authorization checks -- Media assets and BOM exports accessible by any authenticated user (HIGH)
- No network policies in Kubernetes -- Flat network allows lateral movement between all pods (CRITICAL)
- Near-zero test coverage -- Only 3 test files across 11 services + 1 frontend (HIGH)
openlintel/
+-- apps/web/ # Next.js 15 frontend (React 19, tRPC, Three.js)
+-- services/ # 11 Python FastAPI microservices
| +-- design-engine/ # AI design generation (LangGraph)
| +-- vision-engine/ # Floor plan digitization, room segmentation
| +-- media-service/ # File upload, storage, thumbnails
| +-- bom-engine/ # Bill of Materials generation
| +-- drawing-generator/ # DXF/IFC export
| +-- cutlist-engine/ # Material cutting optimization
| +-- mep-calculator/ # MEP (Mechanical/Electrical/Plumbing)
| +-- catalogue-service/ # Product catalog + Meilisearch
| +-- project-service/ # Project management, change orders
| +-- procurement-service/ # Vendor management, procurement
| +-- collaboration/ # Real-time collaboration (Socket.IO)
+-- ml/ # 5 ML pipeline packages
| +-- floor-plan-digitizer/ # VLM + DXF generation
| +-- design-gen/ # LangGraph design generation
| +-- room-segmentation/ # SAM2 + VLM room detection
| +-- product-matching/ # CLIP embeddings + Meilisearch
| +-- measurement/ # Depth estimation + calibration
+-- packages/ # 5 shared packages
| +-- python-shared/ # Auth, DB, Redis, LLM, middleware
| +-- db/ # Drizzle ORM, schema, migrations
| +-- ui/ # Shared React UI components (shadcn)
| +-- core/ # TypeScript types
| +-- config/ # Shared config
+-- infra/ # Infrastructure as Code
| +-- k8s/ # Kubernetes manifests
| +-- docker/ # Dockerfiles
| +-- terraform/ # AWS EKS + RDS + S3
+-- data/ # Building code datasets (JSON)
+-- sampledb/ # SQL seed scripts (13 files)
- Well-decomposed microservices -- Each service has a clear bounded context (design, media, BOM, MEP, etc.)
- Shared package pattern --
python-sharedavoids duplication of auth, DB, Redis, LLM client code - Modern tech choices -- Next.js 15 App Router, React 19, FastAPI, LangGraph, SAM2
- Infrastructure as Code -- Full Terraform + K8s manifests for reproducible deployment
- Building code dataset -- Structured JSON for US IRC, EU Eurocode, UK Regs, India NBC
| Issue | Severity | Description |
|---|---|---|
| No API Gateway | HIGH | Services exposed directly; no rate limiting, circuit breaking, or unified auth at gateway level |
| No Event Bus | MEDIUM | Services communicate via HTTP; no async event-driven patterns for long-running workflows |
| No Service Mesh | MEDIUM | No Istio/Linkerd for mTLS, traffic management, or observability between services |
| Monorepo Coupling | MEDIUM | Python services share code via python-shared but no versioning strategy; breaking changes propagate |
| No Feature Flags | MEDIUM | All features deploy at once; no ability to A/B test or gracefully rollback individual features |
Files Affected:
infra/k8s/secrets.yaml-- Base64-encoded credentials (line 25, 28, 31, 34, 49, 52)docker-compose.yml-- Plaintext MinIO credentials (lines 45-46, 88-89)
Decoded secrets found in secrets.yaml:
| Secret | Decoded Value | Risk |
|---|---|---|
DATABASE_URL |
postgresql://openlintel:change-me@postgres:5432/openlintel |
DB access |
NEXTAUTH_SECRET |
change-me-to-a-random-32-char-string |
Session forgery |
JWT_SECRET |
change-me-to-a-secure-random-string |
Token forgery |
MINIO_SECRET_KEY |
change-me-in-production |
Storage access |
MEILI_MASTER_KEY |
change-me-in-production |
Search admin |
API_KEY_ENCRYPTION_SECRET |
dev-encryption-secret-32chars!! |
Key decryption |
Recommendation: Remove secrets.yaml from version control entirely. Use Kubernetes External Secrets Operator (ESO) with AWS Secrets Manager. Add infra/k8s/secrets.yaml to .gitignore.
File: apps/web/src/app/api/payments/webhook/route.ts (lines 19, 46-56)
Issue: When STRIPE_WEBHOOK_SECRET is empty string, the handler falls back to parsing unsigned JSON -- allowing any attacker to inject fake payment events.
// VULNERABLE: Falls back to unsigned parsing
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET ?? "";
// ...
if (!webhookSecret) {
event = JSON.parse(body); // No signature verification!
}Recommendation: Reject all webhook requests when the secret is not configured:
if (!process.env.STRIPE_WEBHOOK_SECRET) {
return NextResponse.json({ error: "Webhook not configured" }, { status: 503 });
}| Endpoint | File | Issue |
|---|---|---|
GET /api/v1/media/{media_id}/url |
services/media-service/src/routers/assets.py:123-140 |
Authenticated user can access ANY media_id without ownership check |
GET /api/v1/media/{media_id}/thumbnail |
services/media-service/src/routers/assets.py:162-176 |
Same -- no ownership verification |
GET /api/bom/export/{bomId} |
apps/web/src/app/api/bom/export/[bomId]/route.ts |
User can export any BOM by guessing ID |
PUT /api/v1/products/{product_id} |
services/catalogue-service/src/routers/products.py:341 |
Field names from user input used in SQL SET clause without whitelist |
Impact: Any authenticated user can access, modify, or export resources belonging to other users.
Recommendation: Add ownership verification queries before returning resources. Whitelist allowed update fields.
File: services/media-service/src/routers/assets.py (lines 71-80)
# VULNERABLE: Simple substring match without UUID validation
if media_id in key: # Attacker sends media_id="../admin/"Recommendation: Validate media_id as UUID format before S3 lookup:
MEDIA_ID_PATTERN = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")
if not MEDIA_ID_PATTERN.match(media_id):
raise HTTPException(status_code=400, detail="Invalid media_id")File: apps/web/src/lib/llm-client.ts (lines 98-99, 127-128, 155-156)
Issue: Raw LLM API error messages (potentially containing API keys, request details) returned to client.
Recommendation: Log full errors server-side; return generic messages to client.
File: apps/web/src/lib/crypto.ts (line 11)
Issue: Uses first 32 bytes of raw secret for AES-256-GCM without proper key derivation (no PBKDF2/scrypt/argon2).
Recommendation: Derive encryption key using PBKDF2:
const key = crypto.pbkdf2Sync(secret, salt, 100000, 32, 'sha256');File: packages/python-shared/src/openlintel_shared/middleware.py (lines 48-54)
allow_methods=["*"], # All HTTP methods
allow_headers=["*"], # All headers
allow_credentials=True # With credentials!Recommendation: Restrict to specific methods (GET, POST, PUT, DELETE, OPTIONS) and headers (Content-Type, Authorization, X-Request-ID).
File: packages/python-shared/src/openlintel_shared/config.py (lines 35-36, 42, 44)
MINIO_ACCESS_KEY: str = "minioadmin"
MINIO_SECRET_KEY: str = "minioadmin"
JWT_SECRET: str = "replace-with-a-secure-random-string"Recommendation: Add @field_validator to reject placeholder values and require minimum entropy.
File: apps/web/src/app/api/uploads/[key]/route.ts (lines 15-16)
Issue: decodeURIComponent(key) without validation for .. path segments.
Recommendation: Whitelist characters: /^[a-zA-Z0-9\/_.-]+$/.
Files:
services/design-engine/src/routers/designs.py(lines 234-237)services/project-service/src/routers/change_orders.py(lines 218-237)
raise HTTPException(
status_code=500,
detail=f"Impact analysis failed: {exc}", # Leaks internals
)Recommendation: Return generic error messages. Log full details server-side.
| Finding | Severity | File | Description |
|---|---|---|---|
| God Components | HIGH | apps/web/src/app/(dashboard)/dashboard/page.tsx |
Single component handles listing, creating, filtering, dialogs, mutations. Extract to separate components. |
| No Error Boundaries | HIGH | apps/web/src/app/layout.tsx |
Root layout has no ErrorBoundary. Any component crash takes down the entire app. |
| Prop Drilling | MEDIUM | Multiple files | projectId passed through deep component trees. Create ProjectContext or useProjectId() hook. |
| Circular Dependency Risk | HIGH | lib/collaboration.ts + hooks/use-realtime-notifications.ts |
Both connect to same Socket.IO service with duplicate logic. Abstract into RealtimeService. |
| No Feature Flag System | MEDIUM | -- | All features deploy atomically. No ability to toggle, A/B test, or rollback. |
| Finding | Severity | File | Description |
|---|---|---|---|
| Missing Memoization (Sidebar) | HIGH | components/sidebar.tsx |
Navigation items array recreated on every render. Wrap with React.memo, memoize arrays. |
| Missing Memoization (3D Scene) | HIGH | components/editor-3d/scene.tsx |
Canvas and children re-render on parent changes. No useCallback on handlers. |
| No Query Caching Strategy | HIGH | lib/trpc/provider.tsx (lines 15-25) |
Default QueryClient settings. Notifications poll every 30s. Use SSE instead. |
| Fake Upload Progress | MEDIUM | components/file-upload.tsx (lines 32-55) |
Progress hardcoded (10%, 30%, 80%, 100%) without actual tracking. Misleading for large files. |
| BOM Table Not Memoized | MEDIUM | components/bom-table.tsx (lines 57-60) |
Sort triggers full re-render. Wrap in useMemo. |
| Unbounded Model Cache | LOW | lib/gltf-loader.ts (lines 74-90) |
In-memory cache grows without limit. Implement LRU with max size. |
| No Lazy Loading (Admin) | MEDIUM | app/(admin)/admin/page.tsx |
All stats, activity, health loaded eagerly. No pagination or virtualization. |
| Finding | Severity | File | Description |
|---|---|---|---|
Excessive as any |
HIGH | dashboard/page.tsx:174, project/[id]/page.tsx:211,223 |
(project as any).rooms -- breaks type safety. Properly type query results. |
| Unsafe Socket Event Types | MEDIUM | hooks/use-realtime-notifications.ts:45-59 |
Socket events cast to types without Zod validation. |
| Generic Error Messages | MEDIUM | server/trpc/routers/room.ts:30 |
throw new Error('Room not found') -- use TRPCError({ code: 'NOT_FOUND' }). |
| Finding | Severity | File | Description |
|---|---|---|---|
| Missing ARIA on Notifications | HIGH | components/topnav.tsx:57-62 |
Bell icon button has no aria-label. Screen readers can't identify. |
| Missing Label on File Input | HIGH | components/file-upload.tsx:101-107 |
File input has no associated <label>. |
| No Keyboard Shortcuts in 3D Editor | MEDIUM | components/editor-3d/toolbar.tsx |
Shows shortcut hints (V, G, R, S, M) but no keydown handlers implemented. |
| No Focus Trap in Dropdowns | MEDIUM | components/notification-bell.tsx:40-55 |
Custom dropdown with no ESC handling, no focus trap. Use Radix UI Popover. |
| Low Color Contrast | LOW | components/bom-table.tsx:23-37 |
text-stone-700 on bg-stone-100 may fail WCAG AA. |
| Finding | Severity | File | Description |
|---|---|---|---|
| No Pagination on Notifications | HIGH | server/trpc/routers/notification.ts:7-24 |
Supports limit but no cursor/offset. |
| Missing Request Timeouts | HIGH | app/api/jobs/floor-plan-digitize/route.ts:54 |
fetch() to vision-engine has no timeout. Can hang indefinitely. |
| No Retry on LLM Calls | MEDIUM | lib/llm-client.ts:74-162 |
No exponential backoff. Transient failures cause complete failure. |
| Form Not Preserved on Error | MEDIUM | dashboard/page.tsx:43-55 |
Create project form clears on failure. Should only clear on success. |
| Multiple Notification Systems | MEDIUM | -- | Toast + tRPC polling + WebSocket -- can cause duplicates/missed notifications. |
| Service | Lines | Health | Key Issues |
|---|---|---|---|
| design-engine | ~2,500 | Fair | Exception leakage, no pipeline timeout, missing tests |
| vision-engine | ~1,800 | Good | Clean pipeline architecture |
| media-service | ~1,500 | Poor | Authorization bypass, path traversal, missing validation |
| bom-engine | ~2,200 | Fair | Fallback status misleading, unvalidated enum conversion |
| drawing-generator | ~1,000 | Good | Clean IFC/DXF export |
| cutlist-engine | ~800 | Good | Well-structured optimization |
| mep-calculator | ~1,200 | Good | Only service with tests |
| catalogue-service | ~2,000 | Fair | N+1 query, SQL injection risk in update, hardcoded Meili key |
| project-service | ~1,800 | Fair | Bare exception in change orders, exception leakage |
| procurement-service | ~1,200 | Good | Clean vendor management |
| collaboration | ~800 | Good | Socket.IO patterns solid |
File: services/catalogue-service/src/routers/products.py (line 341)
Severity: HIGH
for field, value in update_data.items():
set_clauses.append(f"{field} = :{field}") # User controls field names!Fix: Whitelist allowed update fields:
ALLOWED_UPDATES = {"name", "description", "sku", "brand", "price", "category"}
for field, value in update_data.items():
if field not in ALLOWED_UPDATES:
continueFile: services/catalogue-service/src/routers/products.py (lines 464-478)
Severity: MEDIUM
for match in similar:
product_result = await db.execute(
text("SELECT * FROM products WHERE id = :id"),
{"id": match["product_id"]}, # N separate queries!
)Fix: Batch with WHERE id = ANY(:ids).
File: services/design-engine/src/routers/designs.py (lines 179-191)
Severity: MEDIUM
Background task run_pipeline has no timeout. Can hold resources indefinitely.
Fix: Wrap in asyncio.wait_for(pipeline, timeout=3600).
File: services/bom-engine/src/agents/bom_agent.py (lines 237-244)
Severity: MEDIUM
Returns BOMStatus.EXTRACTING even when LLM extraction fails and fallback data is used. Users can't distinguish quality.
Fix: Add BOMStatus.FALLBACK status.
Files: packages/python-shared/src/openlintel_shared/db.py (lines 87, 121, 200)
Severity: HIGH
except Exception: catches SystemExit, KeyboardInterrupt. Use specific exception types.
| Finding | Severity | File | Description |
|---|---|---|---|
| Hardcoded credentials | MEDIUM | config.py:35-36 |
minioadmin/minioadmin defaults |
| Resource leak in PubSub | LOW | redis_client.py:157-186 |
Returned PubSub not auto-closed. Provide async context manager. |
| Hardcoded Meili key | MEDIUM | catalogue-service/search.py:67 |
openlintel_dev_key in code |
| Missing input validation | MEDIUM | media-service/upload.py:117-125 |
category param accepts arbitrary strings. Use enum. |
| Pipeline | Purpose | Quality | Issues |
|---|---|---|---|
| floor-plan-digitizer | VLM extraction + DXF gen | Good | Relies on external VLM; no fallback if model unavailable |
| design-gen | LangGraph design generation | Good | Well-structured graph with nodes; prompts could leak if errors exposed |
| room-segmentation | SAM2 + VLM detection | Good | Heavy model loads; no lazy loading of SAM2 weights |
| product-matching | CLIP + Meilisearch | Good | Embedding dimension mismatch not validated |
| measurement | Depth estimation + calibration | Good | Multi-view fusion well-implemented |
| Finding | Severity | File | Description |
|---|---|---|---|
| No model version pinning | MEDIUM | ML pyproject.toml files | Model weights fetched at runtime without checksum verification |
| No GPU memory management | MEDIUM | room-segmentation/sam2_wrapper.py |
SAM2 model loaded without GPU memory limit. OOM risk. |
| Prompt injection risk | MEDIUM | design-gen/prompts.py |
User room descriptions injected into LLM prompts without sanitization |
| No batch processing limits | LOW | product-matching/indexer.py |
Indexing has no batch size cap. Large catalogs may exhaust memory. |
File: packages/db/drizzle/0000_pink_squadron_supreme.sql
Foreign key columns without indexes cause slow JOINs and CASCADE deletes:
| Table | Column | Used In | Impact |
|---|---|---|---|
accounts |
user_id |
Auth lookups | Slow login |
projects |
user_id |
Dashboard listing | Slow page load |
rooms |
project_id |
Project detail | Slow navigation |
uploads |
user_id |
Upload listing | Slow file browsing |
uploads |
project_id |
Project uploads | Slow queries |
uploads |
room_id |
Room uploads | Slow queries |
design_variants |
room_id |
Design listing | Slow room page |
user_api_keys |
user_id |
API key lookup | Slow settings |
Recommendation: Create migration:
CREATE INDEX idx_accounts_user_id ON accounts(user_id);
CREATE INDEX idx_projects_user_id ON projects(user_id);
CREATE INDEX idx_rooms_project_id ON rooms(project_id);
CREATE INDEX idx_uploads_user_id ON uploads(user_id);
CREATE INDEX idx_uploads_project_id ON uploads(project_id);
CREATE INDEX idx_uploads_room_id ON uploads(room_id);
CREATE INDEX idx_design_variants_room_id ON design_variants(room_id);
CREATE INDEX idx_user_api_keys_user_id ON user_api_keys(user_id);updated_at columns exist but no database triggers auto-update them. Application code must remember to set them.
spec_json and metadata JSONB columns have no CHECK constraints or schema validation.
Directory: sampledb/ (13 SQL files)
Well-structured seed data covering all major entities. Good for development and testing.
Severity: CRITICAL
Finding: Zero NetworkPolicy resources. All pods communicate freely.
Impact: Lateral movement between any service. Compromised pod can reach database directly.
Fix: Deploy deny-all default policy + whitelist required paths.
Severity: CRITICAL
Finding: No securityContext in any deployment. All containers run as root.
Missing controls: runAsNonRoot, readOnlyRootFilesystem, allowPrivilegeEscalation: false, capabilities.drop: ALL
Severity: HIGH
Finding: 12 instances of :latest across all K8s manifests.
Impact: Non-reproducible deployments, no audit trail.
Fix: Use SHA256 digests or semantic version tags.
Severity: MEDIUM
Finding: Only web and design-engine have HPA. Other 9 services have fixed replicas.
Severity: MEDIUM Finding: No PDB resources. Cluster upgrades can take down all pods simultaneously.
| Finding | Severity | Files | Description |
|---|---|---|---|
| Running as root | HIGH | All service Dockerfiles | No USER directive. Add RUN useradd -u 1000 appuser && USER appuser. |
| No HEALTHCHECK | MEDIUM | All service Dockerfiles | Add HEALTHCHECK directive for container orchestration. |
| Unpinned base images | LOW | All Dockerfiles | python:3.12-slim should be pinned by digest. |
| Finding | Severity | File | Description |
|---|---|---|---|
| EKS public endpoint wide open | MEDIUM | compute.tf:54 |
public_access_cidrs = ["0.0.0.0/0"]. Restrict to VPN/office CIDRs. |
| Single NAT gateway | MEDIUM | networking.tf:82-91 |
Single AZ. Creates single point of failure. Deploy per-AZ. |
| DB password in outputs | MEDIUM | outputs.tf:61 |
Even with sensitive = true, appears in state file. Remove from outputs. |
| No IRSA (IAM Roles for Service Accounts) | HIGH | -- | No per-service IAM roles. All pods share node IAM role. |
| Default environment "staging" | MEDIUM | variables.tf:18 |
terraform apply without -var deploys staging. Remove default; require explicit. |
| State management | GOOD | main.tf:24-31 |
S3 backend with DynamoDB locking and encryption. Well configured. |
| Finding | Severity | Description |
|---|---|---|
Hardcoded minioadmin |
MEDIUM | Lines 45-46, 88-89. Use .env.local. |
| Missing healthchecks | MEDIUM | 8 of 11 services lack healthcheck definitions. |
| No resource limits | LOW | No mem_limit or cpus constraints. Dev environments can exhaust host resources. |
File: .github/workflows/ci.yml
| Missing Step | Impact | Recommendation |
|---|---|---|
| Dependency vulnerability scanning | Known CVEs in deps not detected | Add npm audit + pip install safety && safety check |
| Container image scanning | Vulnerable base images not caught | Add Trivy or Grype scan step |
| SAST (Static Analysis) | Code vulnerabilities not caught | Add CodeQL for JS/Python |
| Secrets scanning | Leaked secrets not detected | Add TruffleHog or git-secrets |
| License compliance | GPL dependencies not flagged | Add license checker |
- TypeScript type checking
- ESLint + Ruff linting
- Python unit tests (where they exist)
- Docker build matrix for all services
- pnpm caching for faster builds
- No deployment stages (no staging -> production promotion)
- No smoke tests after deployment
- No rollback automation
- Python deps installed without hash verification
+---------------------------------------------------------------------+
| TEST COVERAGE INVENTORY |
+---------------------------------------------------------------------+
| Component | Test Files | Coverage Est. | Status |
|------------------------|-----------|---------------|----------------|
| apps/web/ | 0 | 0% | NO TESTS |
| services/design-engine | 0 | 0% | NO TESTS |
| services/vision-engine | 0 | 0% | NO TESTS |
| services/media-service | 0 | 0% | NO TESTS |
| services/bom-engine | 0 | 0% | NO TESTS |
| services/mep-calculator| 3 | ~40% | PARTIAL |
| services/catalogue-svc | 0 | 0% | NO TESTS |
| services/project-svc | 0 | 0% | NO TESTS |
| services/procurement | 0 | 0% | NO TESTS |
| services/collaboration | 0 | 0% | NO TESTS |
| services/cutlist-engine| 0 | 0% | NO TESTS |
| services/drawing-gen | 0 | 0% | NO TESTS |
| ml/ pipelines | 0 | 0% | NO TESTS |
| packages/python-shared | 0 | 0% | NO TESTS |
| packages/db | 0 | 0% | NO TESTS |
| E2E tests | 0 | 0% | NO TESTS |
+---------------------------------------------------------------------+
| TOTAL: 3 test files across entire project |
| ESTIMATED OVERALL COVERAGE: ~3% |
+---------------------------------------------------------------------+
- Authentication flows -- No tests for login, session, JWT validation
- Payment webhook handling -- No tests for Stripe integration
- File upload/download -- No tests for media pipeline
- Authorization checks -- No tests verifying access control
- Encryption/decryption -- No tests for crypto.ts operations
- LLM agent pipelines -- No tests for BOM, design generation agents
- Database migrations -- No tests for schema changes
- E2E user flows -- No Cypress/Playwright tests
Implement testing in priority order:
- Security-critical paths -- auth, payments, authorization (unit tests)
- API contract tests -- all tRPC routers and FastAPI endpoints
- Integration tests -- database operations, S3 operations
- E2E tests -- core user flow (create project -> upload -> generate design -> export)
- ML pipeline tests -- input/output validation, edge cases
- Consistent use of async/await across Python services
- Good separation of concerns (routers, services, agents)
- Proper use of dependency injection via FastAPI
Depends() - Structured logging with context (
structlog) - Shared middleware and auth patterns via
python-shared - TypeScript strict mode in frontend
- shadcn/ui component library for consistent UI
- Drizzle ORM for type-safe database access
| Pattern | Count | Severity | Description |
|---|---|---|---|
as any type casts |
5+ | HIGH | Breaks TypeScript safety. Use proper types. |
Bare except Exception |
6+ | HIGH | Catches too broadly. Use specific exception types. |
| Hardcoded URLs | 15+ | MEDIUM | Service URLs throughout codebase. Use env vars + config. |
| Empty catch blocks | 4+ | MEDIUM | Silent failures. At minimum, log errors. |
| Magic numbers | 10+ | LOW | Undocumented constants. Extract to named constants. |
| Duplicated formatting | 3+ | LOW | room.type.replace(/_/g, ' ') repeated. Extract utility. |
- Next.js 15 / React 19 -- Latest
- tRPC v11 -- Latest
- Three.js -- Latest
- Drizzle ORM -- Latest
- Verdict: Modern, well-maintained dependencies
- FastAPI >=0.111 -- Good, but overly broad range
- SQLAlchemy >=2.0 -- Latest async support
- Pydantic >=2.7 -- Latest
- LiteLLM >=1.40 -- Good
- LangGraph >=0.1 -- Very broad range for pre-1.0 library
- Verdict: Good choices, tighten version ranges
| # | Category | Status | Findings |
|---|---|---|---|
| A01 | Broken Access Control | FAIL | Media asset authz bypass, BOM export no ownership check |
| A02 | Cryptographic Failures | WARN | Weak key derivation, placeholder secrets in code |
| A03 | Injection | FAIL | SQL injection via dynamic columns, path traversal in media |
| A04 | Insecure Design | WARN | No rate limiting, no circuit breakers, no API gateway |
| A05 | Security Misconfiguration | FAIL | Hardcoded creds, permissive CORS, no security headers |
| A06 | Vulnerable Components | PASS | Dependencies generally up-to-date |
| A07 | Auth Failures | WARN | JWT/NextAuth solid, but Stripe webhook bypassable |
| A08 | Data Integrity Failures | WARN | No webhook signature enforcement, no SBOM |
| A09 | Logging & Monitoring | WARN | Structured logging exists but no alerting, no SIEM |
| A10 | SSRF | WARN | S3 path handling could be tightened |
OWASP Compliance Score: 3/10 categories PASS, 4 WARN, 3 FAIL
| # | Task | Effort | Impact |
|---|---|---|---|
| 1 | Remove secrets from version control; implement External Secrets Operator | 2 days | Eliminates credential exposure |
| 2 | Fix Stripe webhook signature bypass | 1 hour | Prevents payment fraud |
| 3 | Add authorization checks to media-service and BOM export | 1 day | Prevents unauthorized data access |
| 4 | Add Kubernetes NetworkPolicies | 1 day | Prevents lateral movement |
| 5 | Add securityContext to all K8s deployments | 0.5 day | Prevents container escape |
| 6 | Fix SQL injection in catalogue-service product update | 1 hour | Prevents data manipulation |
| 7 | Add UUID validation to media_id | 1 hour | Prevents path traversal |
| # | Task | Effort | Impact |
|---|---|---|---|
| 8 | Add Error Boundaries to frontend | 1 day | Prevents full-app crashes |
| 9 | Write tests for auth, payments, authorization | 3 days | Validates security controls |
| 10 | Add CI/CD security scanning (Trivy, CodeQL, TruffleHog) | 1 day | Catches future vulnerabilities |
| 11 | Replace :latest tags with versioned images |
0.5 day | Reproducible deployments |
| 12 | Add USER directive to all Dockerfiles | 0.5 day | Non-root containers |
| 13 | Fix bare exception handlers across Python services | 1 day | Better error diagnosis |
| 14 | Add request timeouts to all service-to-service calls | 1 day | Prevents hanging requests |
| 15 | Create database indexes on foreign keys | 0.5 day | Significant query speedup |
| # | Task | Effort | Impact |
|---|---|---|---|
| 16 | Add React.memo and useMemo to heavy components | 2 days | Frontend performance |
| 17 | Implement cursor-based pagination | 2 days | Scalable list queries |
| 18 | Add HPA to remaining services | 1 day | Auto-scaling |
| 19 | Fix N+1 query in visual search | 0.5 day | Catalogue performance |
| 20 | Add ARIA labels and keyboard navigation | 2 days | Accessibility compliance |
| 21 | Implement retry logic with backoff for LLM calls | 1 day | Resilience |
| 22 | Add PodDisruptionBudgets | 0.5 day | Zero-downtime upgrades |
| 23 | Tighten CORS configuration | 0.5 day | Reduced attack surface |
| # | Task | Effort | Impact |
|---|---|---|---|
| 24 | Add E2E test suite (Playwright) | 5 days | Full flow confidence |
| 25 | Implement feature flag system | 2 days | Safe rollouts |
| 26 | Add API gateway (rate limiting, circuit breaking) | 3 days | Production readiness |
| 27 | Deploy service mesh (Istio/Linkerd) | 3 days | mTLS, traffic management |
| 28 | Add OpenTelemetry distributed tracing | 2 days | Observability |
| 29 | Deploy Prometheus + Grafana monitoring | 2 days | Alerting and dashboards |
| 30 | Comprehensive API documentation | 3 days | Developer experience |
| Phase | Duration | Priority |
|---|---|---|
| Phase 1 | 1 week | Do NOW |
| Phase 2 | 2 weeks | Before production |
| Phase 3 | 3 weeks | First month post-launch |
| Phase 4 | 4 weeks | Ongoing improvement |
| ID | Severity | Category | File | Finding |
|---|---|---|---|---|
| SEC-001 | CRITICAL | Security | infra/k8s/secrets.yaml |
Hardcoded secrets in version control |
| SEC-002 | CRITICAL | Security | docker-compose.yml |
Plaintext credentials in compose file |
| SEC-003 | HIGH | Security | apps/web/.../webhook/route.ts |
Stripe webhook signature bypass |
| SEC-004 | HIGH | Security | services/media-service/.../assets.py |
Missing authorization on media retrieval |
| SEC-005 | HIGH | Security | services/media-service/.../assets.py |
Path traversal via substring match |
| SEC-006 | HIGH | Security | services/catalogue-service/.../products.py |
SQL injection via dynamic column names |
| SEC-007 | HIGH | Security | apps/web/src/lib/llm-client.ts |
LLM API errors exposed to client |
| SEC-008 | HIGH | Security | apps/web/src/lib/crypto.ts |
Weak key derivation for AES-256 |
| SEC-009 | HIGH | Security | apps/web/.../bom/export/[bomId]/route.ts |
BOM export missing ownership check |
| SEC-010 | MEDIUM | Security | packages/python-shared/.../middleware.py |
CORS too permissive |
| SEC-011 | MEDIUM | Security | packages/python-shared/.../config.py |
Hardcoded default credentials |
| SEC-012 | MEDIUM | Security | apps/web/.../uploads/[key]/route.ts |
Storage key path traversal risk |
| SEC-013 | MEDIUM | Security | services/design-engine/.../designs.py |
Exception messages leaked to clients |
| SEC-014 | MEDIUM | Security | services/project-service/.../change_orders.py |
Exception messages leaked to clients |
| SEC-015 | MEDIUM | Security | services/catalogue-service/.../search.py |
Hardcoded Meilisearch dev key |
| SEC-016 | MEDIUM | Security | ml/design-gen/.../prompts.py |
Prompt injection risk in user inputs |
| K8S-001 | CRITICAL | Infrastructure | infra/k8s/ |
No NetworkPolicy resources |
| K8S-002 | CRITICAL | Infrastructure | infra/k8s/ |
No securityContext on any deployment |
| K8S-003 | HIGH | Infrastructure | infra/k8s/*.yaml |
:latest image tags (12 instances) |
| K8S-004 | MEDIUM | Infrastructure | infra/k8s/ |
Missing HPA on 9 of 11 services |
| K8S-005 | MEDIUM | Infrastructure | infra/k8s/ |
No PodDisruptionBudgets |
| K8S-006 | MEDIUM | Infrastructure | infra/k8s/ |
No monitoring/Prometheus config |
| K8S-007 | MEDIUM | Infrastructure | infra/k8s/ |
Missing cert-manager ClusterIssuer |
| K8S-008 | MEDIUM | Infrastructure | infra/k8s/configmap.yaml |
Hardcoded internal service URLs |
| DOC-001 | HIGH | Docker | All service Dockerfiles | Running as root (no USER directive) |
| DOC-002 | MEDIUM | Docker | All service Dockerfiles | No HEALTHCHECK directive |
| DOC-003 | LOW | Docker | All Dockerfiles | Base images not pinned by digest |
| TF-001 | HIGH | Terraform | -- | No IRSA (pod-level IAM roles) |
| TF-002 | MEDIUM | Terraform | compute.tf:54 |
EKS public endpoint open to 0.0.0.0/0 |
| TF-003 | MEDIUM | Terraform | networking.tf:82-91 |
Single NAT gateway (no HA) |
| TF-004 | MEDIUM | Terraform | outputs.tf:61 |
DB password in Terraform output |
| TF-005 | MEDIUM | Terraform | variables.tf:18 |
Default environment "staging" |
| CI-001 | HIGH | CI/CD | .github/workflows/ci.yml |
No dependency vulnerability scanning |
| CI-002 | HIGH | CI/CD | .github/workflows/ci.yml |
No container image scanning |
| CI-003 | MEDIUM | CI/CD | .github/workflows/ci.yml |
No SAST (CodeQL/Semgrep) |
| CI-004 | HIGH | CI/CD | .github/workflows/ci.yml |
No secrets scanning |
| FE-001 | HIGH | Frontend | dashboard/page.tsx |
God component (too many responsibilities) |
| FE-002 | HIGH | Frontend | app/layout.tsx |
No Error Boundaries |
| FE-003 | HIGH | Frontend | components/sidebar.tsx |
Missing React.memo / memoization |
| FE-004 | HIGH | Frontend | components/editor-3d/scene.tsx |
Missing memoization on 3D Canvas |
| FE-005 | HIGH | Frontend | lib/trpc/provider.tsx |
No query caching strategy |
| FE-006 | HIGH | Frontend | lib/collaboration.ts + hooks |
Circular dependency risk |
| FE-007 | HIGH | Frontend | dashboard/page.tsx:174 |
as any type casts |
| FE-008 | HIGH | Frontend | components/topnav.tsx:57-62 |
Missing ARIA on notifications |
| FE-009 | HIGH | Frontend | components/file-upload.tsx:101-107 |
Missing label on file input |
| FE-010 | HIGH | Frontend | server/trpc/routers/notification.ts |
No pagination support |
| FE-011 | HIGH | Frontend | app/api/jobs/floor-plan-digitize/route.ts |
Missing request timeouts |
| FE-012 | MEDIUM | Frontend | components/file-upload.tsx |
Fake upload progress |
| FE-013 | MEDIUM | Frontend | components/bom-table.tsx |
Sort not memoized |
| FE-014 | MEDIUM | Frontend | hooks/use-realtime-notifications.ts |
Unsafe socket event types |
| FE-015 | MEDIUM | Frontend | server/trpc/routers/room.ts |
Generic error messages |
| FE-016 | MEDIUM | Frontend | components/editor-3d/toolbar.tsx |
No keyboard handlers |
| FE-017 | MEDIUM | Frontend | components/notification-bell.tsx |
No focus trap in dropdown |
| FE-018 | MEDIUM | Frontend | server/trpc/routers/admin.ts |
Hardcoded service URLs |
| FE-019 | MEDIUM | Frontend | lib/llm-client.ts |
No retry logic on LLM calls |
| FE-020 | MEDIUM | Frontend | dashboard/page.tsx |
Form not preserved on error |
| FE-021 | MEDIUM | Frontend | -- | Multiple notification systems |
| FE-022 | MEDIUM | Frontend | app/(admin)/admin/page.tsx |
No lazy loading |
| FE-023 | MEDIUM | Frontend | lib/auth.config.ts |
Auth providers hardcoded |
| FE-024 | MEDIUM | Frontend | Multiple files | Prop drilling for projectId |
| FE-025 | LOW | Frontend | lib/gltf-loader.ts |
Unbounded model cache |
| FE-026 | LOW | Frontend | components/bom-table.tsx |
Low color contrast |
| FE-027 | LOW | Frontend | Multiple files | Redundant string formatting |
| FE-028 | LOW | Frontend | components/payment-form.tsx |
Hardcoded currency list |
| FE-029 | MEDIUM | Frontend | app/api/upload/route.ts |
Hardcoded max upload size |
| FE-030 | MEDIUM | Frontend | lib/snap-engine.ts |
Hardcoded grid sizes |
| BE-001 | HIGH | Backend | packages/python-shared/.../db.py |
Bare except catching all exceptions |
| BE-002 | HIGH | Backend | services/project-service/.../change_orders.py |
Bare except in exception handler |
| BE-003 | MEDIUM | Backend | services/design-engine/.../designs.py |
Missing pipeline timeout |
| BE-004 | MEDIUM | Backend | services/bom-engine/.../bom_agent.py |
Misleading fallback status |
| BE-005 | MEDIUM | Backend | services/bom-engine/.../bom_agent.py |
Unvalidated enum conversion |
| BE-006 | MEDIUM | Backend | services/catalogue-service/.../products.py |
N+1 query in visual search |
| BE-007 | MEDIUM | Backend | services/catalogue-service/.../search.py |
Mutable global state |
| BE-008 | MEDIUM | Backend | services/media-service/.../upload.py |
Missing input validation (category) |
| BE-009 | LOW | Backend | Various | Missing type hints on helpers |
| BE-010 | LOW | Backend | Various | Inconsistent error logging patterns |
| BE-011 | LOW | Backend | Various | Magic numbers without constants |
| BE-012 | LOW | Backend | redis_client.py |
PubSub resource leak risk |
| BE-013 | LOW | Backend | Various | Missing docstrings on public APIs |
| BE-014 | LOW | Backend | Various | Vague status values without docs |
| DB-001 | HIGH | Database | drizzle/0000_*.sql |
Missing indexes on 8 foreign key columns |
| DB-002 | MEDIUM | Database | Schema | No auto-update triggers for updated_at |
| DB-003 | LOW | Database | Schema | No CHECK constraints on JSONB fields |
| ML-001 | MEDIUM | ML | ML pyproject.toml files | No model version pinning |
| ML-002 | MEDIUM | ML | room-segmentation/sam2_wrapper.py |
No GPU memory management |
| ML-003 | MEDIUM | ML | design-gen/prompts.py |
Prompt injection risk |
| ML-004 | LOW | ML | product-matching/indexer.py |
No batch processing limits |
| TST-001 | HIGH | Testing | All services | Only 3 test files across entire project |
| TST-002 | HIGH | Testing | apps/web/ |
Zero frontend tests |
| TST-003 | HIGH | Testing | -- | No E2E tests |
| TST-004 | HIGH | Testing | -- | No auth/payment/crypto tests |
| DEP-001 | MEDIUM | Dependencies | Backend pyproject.toml | Overly broad version ranges |
| DEP-002 | LOW | Dependencies | Backend pyproject.toml | Missing security dev tools (bandit, safety) |
| CFG-001 | MEDIUM | Config | docker-compose.yml |
Missing healthchecks on 8 services |
| CFG-002 | MEDIUM | Config | infra/k8s/ingress.yaml |
CORS origin hardcoded |
| CFG-003 | MEDIUM | Config | .env.example |
No separate production example |
| CFG-004 | LOW | Config | Makefile |
.env copy without validation |
| ARCH-001 | HIGH | Architecture | -- | No API gateway |
| ARCH-002 | MEDIUM | Architecture | -- | No event bus / async messaging |
| ARCH-003 | MEDIUM | Architecture | -- | No service mesh |
| ARCH-004 | MEDIUM | Architecture | -- | No feature flag system |
| COMP-001 | MEDIUM | Compliance | docker-compose.yml |
Missing resource limits |
| COMP-002 | LOW | Compliance | -- | No deployment security guide |
| COMP-003 | LOW | Compliance | -- | No production deployment checklist |
OpenLintel has a strong architectural foundation -- the monorepo structure, microservice decomposition, shared packages, and technology choices are all excellent for an AI-powered architecture/design platform. The domain modeling (rooms, designs, BOMs, MEP, procurement) shows deep understanding of the interior design workflow.
However, the codebase is not production-ready in its current state. The combination of:
- Critical security gaps (exposed secrets, authorization bypasses, webhook bypass)
- Near-zero test coverage (3 test files across 407 source files)
- Infrastructure hardening gaps (no network policies, root containers, no security scanning)
...means the platform carries significant risk for any deployment handling real user data or financial transactions.
The remediation roadmap in Phase 1 (1 week) addresses the most dangerous issues. Completing Phases 1-2 would bring the codebase to a reasonable production baseline. Phases 3-4 would elevate it to a mature, observable, and resilient platform.
Bottom Line: Strong vision and architecture. Fix security and testing before going live.
Report generated by comprehensive static analysis of 407 source files across the OpenLintel monorepo. All findings include file paths and line numbers for verification. Recommendations follow OWASP, CIS Kubernetes Benchmark, and AWS Well-Architected Framework guidelines.
This section extends the audit with a complete gap analysis between REQUIREMENTS.md (307 specified features) and the actual codebase, a page-by-page UI/UX teardown, backend API error inventory, and a prioritized desired features roadmap.
+---------------------------------------------------------------------+
| REQUIREMENTS COVERAGE: 125 / 307 (41%) |
+---------------------------------------------------------------------+
| |
| Implemented [########--------------] 125 (41%) |
| Partial [####------------------] 80 (26%) |
| Not Started [#####-----------------] 102 (33%) |
| |
+---------------------------------------------------------------------+
| Req Section | Features | Done | Partial | Not Started | % Complete |
|---|---|---|---|---|---|
| 2 - Input & Capture | 17 | 7 | 6 | 4 | 41% |
| 3 - Design Engine | 18 | 9 | 4 | 5 | 50% |
| 4 - Technical Drawings | 22 | 5 | 11 | 6 | 23% |
| 5 - BOM & Cut Lists | 14 | 6 | 5 | 3 | 43% |
| 6 - Catalogue & Retailer | 15 | 2 | 6 | 7 | 13% |
| 7 - Procurement | 14 | 4 | 6 | 4 | 29% |
| 8 - Civil & MEP | 26 | 11 | 4 | 11 | 42% |
| 9 - Project Execution | 19 | 11 | 4 | 4 | 58% |
| 10 - Collaboration | 13 | 4 | 5 | 4 | 31% |
| 11 - Compliance & Permits | 18 | 5 | 1 | 12 | 28% |
| 12 - Financial Management | 15 | 9 | 2 | 4 | 60% |
| 13 - QA & Handover | 16 | 7 | 6 | 3 | 44% |
| 14 - Platform & Infra | 26 | 9 | 3 | 14 | 35% |
| 15 - AI/ML Capabilities | 19 | 10 | 5 | 4 | 53% |
| 16 - Accessibility | 8 | 0 | 3 | 5 | 0% |
| 17 - Sustainability | 6 | 3 | 0 | 3 | 50% |
| 18 - Post-Completion | 7 | 6 | 0 | 1 | 86% |
| 19 - Regional & Global | 7 | 3 | 1 | 3 | 43% |
| 20 - Non-Functional | 20 | 4 | 8 | 8 | 20% |
| TOTAL | 307 | 125 | 80 | 102 | 41% |
| Requirement | Status | What's Needed |
|---|---|---|
| Retailer self-service portal (CSV/Excel upload) | NOT STARTED | Build brand onboarding flow with CSV import, product validation, bulk upload UI |
| Retailer API integrations (Amazon, IKEA, etc.) | NOT STARTED | Build adapter layer for retailer PIM systems; features2402.md notes this explicitly as missing |
| Product page scraper (with permission) | NOT STARTED | Build web scraper pipeline for product data ingestion |
| Historical price tracking | NOT STARTED | Add product_price_history table, cron to snapshot prices, trend chart in UI |
| Bulk discount calculation | NOT STARTED | Build discount engine based on quantity breaks per vendor |
| Regional price variation | NOT STARTED | Add region-aware pricing with geo-lookup |
| Total cost of ownership calculator | NOT STARTED | Factor in maintenance cycles, energy consumption, replacement frequency |
| Product compatibility checking | NOT STARTED | Build compatibility matrix (e.g., heavy countertop on weak cabinet) |
| Design-linked recommendations | NOT STARTED | AI suggests products matching current design style + color palette + budget |
| Alternative product suggestions | NOT STARTED | For every specified product, show 2-3 alternatives at different price points |
| Requirement | Status | What's Needed |
|---|---|---|
| Construction floor plan (demolition/construction layers) | PARTIAL | Add layer separation in DXF output |
| Detailed elevation drawings (cabinet heights, tile layouts, electrical positions) | PARTIAL | Expand drawing-generator to produce full wall-by-wall elevations |
| Section drawings (false ceiling layers, floor build-up, kitchen counter sections) | PARTIAL | Expand drawing-generator with section cut logic |
| Joinery/millwork details (enlarged details, shelf spacing, drawer mechanisms) | PARTIAL | Combine cut-list engine output with DXF detail generation |
| Structural drawings (load-bearing walls, opening details, countertop support) | NOT STARTED | Build structural analysis module |
| DWG import (not just DXF export) | NOT STARTED | Integrate LibreDWG for DWG reading; currently only exports DXF |
| OBJ/FBX 3D model export | NOT STARTED | Add mesh export formats beyond GLTF |
| Electrical layout drawings with conduit routing | PARTIAL | MEP-calculator generates data; drawing output layer needed |
| Plumbing layout drawings with pipe routing | PARTIAL | Same -- calculation exists, drawing generation missing |
| Requirement | Status | What's Needed |
|---|---|---|
| Multi-factor authentication (MFA) | NOT STARTED | Add TOTP/SMS MFA to NextAuth configuration |
| Auto-save for design changes | NOT STARTED | Implement periodic auto-save with LocalStorage draft + server sync |
| Offline capability | NOT STARTED | Service worker for critical mobile features, IndexedDB for local cache |
| Data export (GDPR compliance) | NOT STARTED | Build "Download My Data" feature exporting all user data in open formats |
| Right to deletion (complete purge) | NOT STARTED | Build cascade deletion across all services for a given user |
| 99.9% uptime SLA infrastructure | NOT STARTED | Deploy multi-AZ, add health monitoring, implement failover |
| Disaster recovery (RPO < 1 hour, RTO < 4 hours) | NOT STARTED | Configure automated DB backups, cross-region replication |
| Consent management (opt-in for AI training, marketing) | NOT STARTED | Build consent management UI and backend tracking |
| Requirement | Status | What's Needed |
|---|---|---|
| Accessibility design mode (wheelchair layouts, grab bars, lever handles) | NOT STARTED | Build accessibility design template library |
| Aging-in-place design templates | NOT STARTED | Non-slip flooring, walk-in showers, wider doorways, grab bars |
| WCAG 2.1 AA compliance for platform UI | PARTIAL | Systematic audit and fix of all color contrast, ARIA, keyboard nav |
| Screen reader support | PARTIAL | Test with NVDA/VoiceOver; fix missing ARIA labels throughout |
| High contrast mode | NOT STARTED | Add CSS custom property toggle for high-contrast theme |
| Multi-language UI | PARTIAL | Localization router exists but no i18n framework (react-intl, next-intl) |
| RTL support (Arabic, Hebrew) | NOT STARTED | Add dir="rtl" support with Tailwind RTL plugin |
| # | Feature | Req Section | Impact | Effort |
|---|---|---|---|---|
| 1 | Mobile App (React Native/Flutter) | 14.2 | Critical for site teams, photo capture, AR | 3-6 months |
| 2 | Structural Analysis (load-bearing walls, modification feasibility) | 8.1 | Safety-critical; blocks wall removal features | 1-2 months |
| 3 | Fire Safety Module (smoke detectors, fire ratings, escape routes) | 8.5 | Safety compliance requirement | 1 month |
| 4 | Retailer API Integrations (live pricing, inventory) | 6.2 | Core business value for procurement | 2-3 months |
| 5 | Permit Management (requirement detection, document prep, tracking) | 11.2 | Legal compliance requirement | 1-2 months |
| 6 | Design Version History (branch, compare, merge, rollback) | 3.4 | Core design workflow feature | 1-2 months |
| 7 | Before/After Comparison Slider | 3.4 | High-value visual feature | 1 week |
| 8 | Client Presentation Mode (slide-deck walkthrough) | 3.4 | Essential for designer-client workflow | 2-3 weeks |
| 9 | Shareable Links (view without login) | 10.3 | Family member review, advisor feedback | 1-2 weeks |
| 10 | E-signature Integration | 10.3 | Digital approval workflow | 2-3 weeks |
| 11 | Chatbot/AI Copilot | 15.2 | "What tile for a hallway?" -- conversational product discovery | 1-2 months |
| 12 | Acoustic Design Module | 8.6 | Home theater, music rooms, STC/IIC ratings | 1 month |
| 13 | Workforce Scheduling Calendar | 9.1 | Crew scheduling across multiple sites | 2-3 weeks |
| 14 | Delay Management (auto-cascade) | 9.2 | When task X delays, auto-update all downstream tasks | 2-3 weeks |
| 15 | Material Usage Tracking (used vs. remaining vs. wasted) | 7.4 | Waste reduction core value proposition | 2-3 weeks |
Severity: HIGH Files Affected:
apps/web/src/app/(dashboard)/dashboard/page.tsx-- line 124 (delete project)apps/web/src/app/(dashboard)/portfolios/page.tsx-- line 68 (delete portfolio)apps/web/src/app/(dashboard)/project/[id]/page.tsx-- line 124 (delete project)apps/web/src/app/(dashboard)/project/[id]/rooms/[roomId]/page.tsx-- line 279 (delete photo)apps/web/src/app/(dashboard)/project/[id]/designs/page.tsx-- line 255 (delete design)
Issue: Native window.confirm() dialogs are used for all destructive operations. These look unprofessional, cannot be styled, and provide no additional context (e.g., "This will delete 5 rooms and 12 designs").
Recommendation: Create a reusable <ConfirmDialog> component with:
- Destructive action styling (red button)
- Context about what will be deleted (counts of affected items)
- Optional "type to confirm" for high-risk actions
- Toast notification after completion
Severity: HIGH
File: apps/web/src/app/layout.tsx
Issue: Zero <ErrorBoundary> components anywhere in the app. If any page component throws (data fetch failure, undefined property access, render error), the entire application crashes with a white screen.
Recommendation:
- Add root ErrorBoundary in
layout.tsx - Add per-page ErrorBoundary in each
(dashboard)layout - Show "Something went wrong" with retry button and error report option
Severity: HIGH
File: apps/web/src/app/(dashboard)/project/[id]/designs/[designId]/page.tsx -- lines 443-481
Issue: Comments tab shows a form and "Comment posted" toast, but there is no actual API call to post comments. The collaboration page (/collaboration/) has a working comment system, but design-level comments are non-functional stubs.
Recommendation: Either integrate the collaboration comment system into design pages or remove the stubbed comments tab to avoid confusing users.
Severity: HIGH Files Affected:
components/payment-form.tsx-- line 63: Only checksparsedAmount <= 0, no min/max, no currency validationproject/[id]/page.tsx-- lines 68-76: Room name only checkstrim(), no min length; dimension inputs allow negative numbersproject/[id]/quality/page.tsx-- lines 232-246: Checkpoint creation allows empty descriptions
Recommendation: Implement comprehensive client-side validation with:
- Zod schemas mirroring server-side validation
- Inline error messages under each field
- Disable submit button until form is valid
- Highlight invalid fields on blur
Severity: MEDIUM Issue: The 3D editor has full undo/redo (Ctrl+Z, Ctrl+Shift+Z), but all other pages lack undo capability. Accidental deletions, status changes, or form submissions cannot be reversed.
Recommendation: Implement "undo" toast notifications (like Gmail's "Message sent - Undo") for:
- Deleting rooms, designs, photos
- Status changes (change orders, milestones)
- Creating items accidentally
Severity: MEDIUM
Issue: Deep routes like /project/[id]/designs/[designId] or /project/[id]/rooms/[roomId] provide no breadcrumb trail. Users cannot see where they are in the hierarchy or navigate back to intermediate levels.
Recommendation: Add breadcrumb component: Dashboard > Project Name > Designs > Design Variant Name
Severity: MEDIUM
File: apps/web/src/components/sidebar.tsx -- lines 55-86
Issue: The project sidebar navigation lists 30+ menu items. The container uses overflow-y-auto but provides no visual indication that more items exist below the fold. Users don't discover features hidden below the scroll.
Recommendation:
- Add scroll shadow (gradient fade at bottom when more items below)
- Group items into collapsible sections (Design, Engineering, Procurement, Management, etc.)
- Add "Quick Jump" search within sidebar
Severity: MEDIUM
File: apps/web/src/app/(dashboard)/dashboard/page.tsx
Issue: When a new user signs up and lands on an empty dashboard, there is no guided tour, no sample project, no getting-started wizard. The empty state simply shows "No projects yet" with a create button.
Recommendation:
- Add interactive onboarding tour (highlight Create Project > Add Room > Upload Photo > Generate Design)
- Offer a "Sample Project" that demonstrates the full pipeline
- Show contextual tooltips on first visit to each feature
Severity: MEDIUM
File: apps/web/src/components/file-upload.tsx -- lines 32-55
Issue: Upload progress is hardcoded: 10% -> 30% -> 80% -> 100% on timer intervals. This is misleading -- for a 10MB file on a slow connection, the bar reaches 80% instantly and then hangs. For a tiny file, it artificially slows down.
Recommendation: Use XMLHttpRequest.upload.onprogress or fetch with ReadableStream for real progress tracking.
Severity: MEDIUM Files Affected: Multiple pages throughout the app
Issue: Toast messages vary wildly in tone, format, and information:
- Change orders: "Change order created" (success, no details)
- Timeline: "Schedule generation started" (misleading -- says started, not completed)
- Payment: "Checkout failed" (error, no recovery suggestion)
- Some mutations have no success toast at all
Recommendation: Create a toast utility with standardized patterns:
- Success: "Created [item name] successfully" with optional undo link
- Error: "Failed to [action]. [Reason]. Try again or contact support."
- Progress: "Generating [item]... This may take a moment."
Severity: MEDIUM Files Affected:
project/[id]/change-orders/page.tsx-- lines 83-112project/[id]/quality/page.tsx-- lines 151-213project/[id]/rooms/[roomId]/page.tsx-- lines 414-484
Issue: Form inputs remain editable while a mutation is in flight. Users can modify values during submission, causing confusion about what was actually saved.
Recommendation: Disable all form inputs and show a loading spinner on the submit button during mutation.isPending.
Severity: MEDIUM Files Affected:
components/topnav.tsx-- line 57 (notification bell)project/[id]/rooms/[roomId]/page.tsx-- line 173 (edit pencil icon)- Editor toolbar icons throughout
Issue: Icon-only buttons provide no text hint. Users must click to discover what they do.
Recommendation: Wrap all icon-only buttons in <Tooltip> from the UI library.
Severity: LOW Issue: While file upload supports drag-and-drop, no list in the app supports drag-to-reorder:
- Room list (reorder priority)
- Punch list items (reorder severity)
- Sidebar navigation (customize layout)
- BOM items (reorder categories)
Recommendation: Add @dnd-kit/sortable for reorderable lists where user preference matters.
Severity: HIGH Files Affected:
project/[id]/payments/page.tsx-- lines 308-350project/[id]/bom/page.tsx-- BOM tableproject/[id]/timeline/page.tsx-- Gantt chart- All data tables throughout the app
Issue: Complex data tables use overflow-x-auto which requires horizontal scrolling on mobile. Column headers misalign when scrolled. Gantt chart is completely unusable on small screens.
Recommendation:
- Use card layout on mobile (stack table rows vertically)
- Implement responsive column hiding (show key columns only on small screens)
- For Gantt chart, switch to a simplified timeline list view on mobile
Severity: MEDIUM Issue: When the user loses internet connectivity, mutations fail silently. There is no visual indicator showing offline status, no queuing of operations, and no retry mechanism.
Recommendation:
- Add offline detection banner ("You are offline. Changes will be saved when reconnected.")
- Queue mutations in IndexedDB
- Retry on reconnection with conflict resolution
Severity: MEDIUM Files Affected:
components/topnav.tsx-- line 44: hardcodedbg-whitecomponents/sidebar.tsx-- line 92: hardcodedbg-gray-50/50- Multiple components use light-only color classes
Issue: The UI library (shadcn/ui) supports dark mode via CSS variables, but many custom components use hardcoded light-mode colors like bg-white, bg-gray-50, hover:bg-gray-100.
Recommendation: Replace all hardcoded color classes with Tailwind's dark: variant or CSS custom properties from the theme.
Severity: HIGH Files Affected:
components/topnav.tsx-- line 57: notification bell has noaria-labelcomponents/file-upload.tsx-- file input has no associated<label>components/editor-3d/toolbar.tsx-- toolbar buttons missingaria-labelcomponents/notification-bell.tsx-- dropdown has noaria-expanded
Recommendation: Audit every interactive element for ARIA compliance. Add aria-label, aria-expanded, aria-haspopup, role attributes as needed.
Severity: MEDIUM
File: project/[id]/timeline/page.tsx -- lines 335-346
Issue: Status badges use color alone to convey meaning (red = critical, green = completed). Colorblind users (8% of males) cannot distinguish states.
Recommendation: Add icons alongside colors: checkmark for completed, warning triangle for critical, clock for in-progress.
Severity: MEDIUM
File: components/notification-bell.tsx -- lines 40-55
Issue: Notification dropdown is a custom-positioned div with z-50. No focus trap, no ESC key handling, no aria-expanded toggling. Keyboard users cannot navigate or dismiss.
Recommendation: Replace with Radix UI <Popover> or <DropdownMenu> which handle focus trapping, keyboard navigation, and ARIA automatically.
Severity: LOW
File: apps/web/src/app/(dashboard)/marketplace/page.tsx
Issue: Search results don't highlight the matching terms. Users can't see why an item matched their query.
Severity: MEDIUM
File: project/[id]/rooms/[roomId]/page.tsx -- lines 261-266
Issue: Room photos use <img> with no onError handler. If the image URL is broken (deleted from S3, expired presigned URL), the user sees a broken image icon.
Recommendation: Add placeholder fallback image and retry button.
Severity: LOW Issue: Right-clicking on any list item (project card, room card, design variant) does nothing. Power users expect context menus for quick actions (Copy, Duplicate, Export, Delete, Open in New Tab).
Severity: MEDIUM Issue: If a user is filling out a complex form (change order, room edit, new project) and accidentally navigates away or loses connection, all unsaved work is lost.
Recommendation: Save form state to localStorage on every keystroke. Restore on return. Clear on successful submit.
Severity: LOW
File: components/topnav.tsx -- lines 59-61
Issue: When unread notifications exceed 9, the badge shows "9+" regardless of whether there are 10 or 500 unread. User has no sense of the true count.
Recommendation: Show actual count (e.g., "23") or "99+" for very high numbers.
Severity: MEDIUM
File: apps/web/src/app/(dashboard)/marketplace/page.tsx
Issue: Search terms, filters (city, specialization), sort order, and pagination state reset when navigating away and back. Users must re-apply filters every time.
Recommendation: Persist filter state in URL query parameters (?q=marble&city=mumbai&page=3).
| ID | Severity | Category | Description |
|---|---|---|---|
| UX-001 | HIGH | Interaction | Browser confirm() for destructive actions |
| UX-002 | HIGH | Stability | No error boundaries -- full crash on component failure |
| UX-003 | HIGH | Completeness | Comment system stubbed in design details |
| UX-004 | HIGH | Validation | Missing form validation across the app |
| UX-005 | MEDIUM | Interaction | No undo for non-editor operations |
| UX-006 | MEDIUM | Navigation | No breadcrumb navigation |
| UX-007 | MEDIUM | Navigation | Sidebar 30+ items without scroll indicator |
| UX-008 | MEDIUM | Onboarding | No first-time user onboarding flow |
| UX-009 | MEDIUM | Feedback | Fake upload progress bar |
| UX-010 | MEDIUM | Feedback | Inconsistent toast notifications |
| UX-011 | MEDIUM | Interaction | Forms not disabled during submission |
| UX-012 | MEDIUM | Interaction | No tooltips on icon-only buttons |
| UX-013 | LOW | Interaction | No drag-and-drop for reordering |
| UX-014 | HIGH | Responsive | Tables break on mobile |
| UX-015 | MEDIUM | Connectivity | No offline indicator |
| UX-016 | MEDIUM | Theming | Incomplete dark mode |
| UX-017 | HIGH | Accessibility | Missing ARIA labels throughout |
| UX-018 | MEDIUM | Accessibility | Color-only status differentiation |
| UX-019 | MEDIUM | Accessibility | No focus trap in custom dropdowns |
| UX-020 | LOW | Search | No search highlighting in results |
| UX-021 | MEDIUM | Resilience | No image fallback on load failure |
| UX-022 | LOW | Interaction | No right-click context menus |
| UX-023 | MEDIUM | Data Loss | No auto-save / draft persistence |
| UX-024 | LOW | Feedback | Notification count shows "9+" without total |
| UX-025 | MEDIUM | State | No filter/sort persistence across navigation |
| Finding | Severity | File : Line | Description |
|---|---|---|---|
| No rate limiting | HIGH | main.py |
No per-user rate limiting on design generation (expensive LLM calls) |
| Silent error swallowing | HIGH | routers/designs.py:302 |
Generic exception handler doesn't bubble up critical API key errors |
| No request validation on internal endpoint | MEDIUM | routers/designs.py:222 |
Fire-and-forget job endpoint accepts unvalidated payloads |
| Missing SSE for progress | MEDIUM | routers/designs.py:315-358 |
Job progress uses polling; should use Server-Sent Events |
| No design comparison API | LOW | -- | Cannot compare two design variants side-by-side via API |
| No design history/versioning | MEDIUM | -- | No version tracking for design iterations |
| Finding | Severity | File : Line | Description |
|---|---|---|---|
| Silent fallback to hardcoded defaults | HIGH | routers/reconstruction.py:290-299 |
VLM dimension estimation failure falls back to fixed values without logging the cause |
| Mesh generation failure logged as warning | MEDIUM | routers/reconstruction.py:167-177 |
Should be error-level log |
| Image download limit hardcoded | MEDIUM | routers/reconstruction.py:125 |
Downloads max 10 images, not configurable |
| No batch processing endpoint | LOW | routers/vision.py |
Cannot process multiple floor plans in one request |
| Finding | Severity | File : Line | Description |
|---|---|---|---|
| Inefficient S3 listing for asset lookup | HIGH | routers/assets.py:71-80 |
Lists ALL uploads and filters client-side instead of database lookup |
| No caching of media lookups | MEDIUM | routers/assets.py:117-153 |
Presigned URL generation not cached in Redis |
| PDF processing skips optimization | MEDIUM | routers/upload.py:147-149 |
PDFs uploaded without any size optimization |
| No virus/malware scanning | MEDIUM | routers/upload.py:106-209 |
Uploaded files not scanned |
| No resumable uploads | MEDIUM | routers/upload.py |
Large uploads cannot resume on failure |
| No automatic EXIF rotation fix | LOW | routers/upload.py |
Photos may display rotated |
| Finding | Severity | File : Line | Description |
|---|---|---|---|
| In-memory store not shared across replicas | HIGH | routers/bom.py:46 |
_bom_store dict is process-local; scaling to N replicas loses data |
| Synchronous BOM agent invocation | MEDIUM | routers/bom.py:84-104 |
Should be async to avoid blocking event loop |
| Misleading fallback status | MEDIUM | agents/bom_agent.py:237-244 |
Returns EXTRACTING status when using fallback data after LLM failure |
| Unvalidated enum conversion | MEDIUM | agents/bom_agent.py:264 |
BudgetTier(state["budget_tier"]) with no try/except |
| No partial result saving | LOW | routers/bom.py:138-224 |
If calculation fails mid-way, all progress is lost |
| Finding | Severity | File : Line | Description |
|---|---|---|---|
| IFC generation failure silently ignored | HIGH | routers/drawings.py:121-131 |
ImportError for IfcOpenShell swallowed; user thinks IFC was generated |
| Individual drawing type failure doesn't halt job | MEDIUM | routers/drawings.py:146-151 |
If elevation drawing fails but floor plan succeeds, job shows success |
| No request schema validation | MEDIUM | routers/drawings.py:169-182 |
Fire-and-forget endpoint accepts arbitrary payloads |
| Drawing types hardcoded | MEDIUM | routers/drawings.py:62-64 |
Cannot request specific drawing types |
| Finding | Severity | File : Line | Description |
|---|---|---|---|
| Sheet size hardcoded to "8x4" | MEDIUM | routers/cutlist_job.py:170 |
Cannot specify custom sheet sizes |
| Fallback always returns bedroom defaults | MEDIUM | routers/cutlist_job.py:86-93 |
If furniture specs missing, assumes bedroom regardless of room type |
| No progress streaming | LOW | routers/cutlist_job.py:101-209 |
Long-running nesting optimization provides no progress updates |
| Finding | Severity | File : Line | Description |
|---|---|---|---|
| Unknown calc_type returns wrong status code | MEDIUM | routers/mep_job.py:153 |
Should return 422 Unprocessable Entity, not 500 |
| Room-specific defaults ignore occupancy | MEDIUM | routers/mep_job.py:40-88 |
Appliance specs don't account for room size variation |
| No parallel MEP calculation | LOW | routers/mep_job.py:91-151 |
Must run electrical, plumbing, HVAC separately; no combined endpoint |
| Missing voltage drop calculation | MEDIUM | routers/electrical.py |
Critical for long wire runs; NEC requirement |
| Missing humidity parameter for HVAC | LOW | routers/hvac.py:29-115 |
Cooling load calculation doesn't account for humidity |
| Finding | Severity | File : Line | Description |
|---|---|---|---|
| N+1 query in visual search | HIGH | routers/products.py:464-478 |
Individual query per match result (up to 20 queries) |
| SQL injection risk via dynamic columns | HIGH | routers/products.py:341 |
User-controlled field names in SET clause |
| user_id parameter unused in search | MEDIUM | routers/products.py:134 |
Declared but never validated or used for filtering |
| Category slug generation lacks uniqueness check | MEDIUM | routers/categories.py:193 |
Auto-generated slugs may collide |
| No soft delete option | MEDIUM | routers/products.py:378-413 |
Hard delete with no recovery; BOM references become orphaned |
| No bulk import endpoint | MEDIUM | -- | Cannot bulk upload product catalog |
| Embedding generation not properly awaited | LOW | routers/products.py:281-284 |
Async embedding generation may not complete before response |
| Finding | Severity | File : Line | Description |
|---|---|---|---|
| Manual db.commit() without transaction context | HIGH | routers/schedule_job.py:201,224 |
Multiple commits without rollback protection |
| Site log sorting relies on dict key ordering | MEDIUM | routers/site_logs.py:125-132 |
Not stable across Python implementations |
| Silent fallback if schedule not in cache | MEDIUM | routers/change_orders.py:164-166 |
Impact analysis proceeds without schedule data |
| Change order type/details lack schema validation | MEDIUM | routers/change_orders.py:188-189 |
Accepts arbitrary change types |
json imported via __import__ instead of import statement |
LOW | routers/schedule_job.py:185 |
Unusual pattern; should use standard import |
| Finding | Severity | File : Line | Description |
|---|---|---|---|
| Phasing agent failure silently ignored | HIGH | routers/orders.py:105-111 |
Procurement orders proceed without proper phasing |
| Delivery status update doesn't sync with order status | MEDIUM | routers/delivery.py:115-116 |
Status transitions not coordinated |
| Delay recomputation on each GET request | MEDIUM | routers/delivery.py:178 |
Expensive calculation on read; should be cached |
| Creates new delivery record without checking existing | MEDIUM | routers/delivery.py:86-89 |
Duplicate delivery records possible |
| Returns empty result instead of 404 | LOW | routers/delivery.py:208-212 |
No orders for project returns 200 with empty array, not 404 |
| # | Issue | Severity | Impact |
|---|---|---|---|
| 1 | No standardized error response format | HIGH | Each service returns errors differently; frontend must handle N different formats |
| 2 | No request ID / correlation tracking | HIGH | Cannot trace requests across distributed services; debugging production issues impossible |
| 3 | 41+ bare except Exception blocks |
HIGH | Errors silently swallowed throughout; masks bugs and causes data inconsistency |
| 4 | No rate limiting on any service | HIGH | All endpoints vulnerable to abuse and DoS |
| 5 | Fire-and-forget without delivery guarantee | MEDIUM | Job dispatch has no retry mechanism; failed dispatches silently lost |
| 6 | No audit logging for data mutations | MEDIUM | No record of who changed what and when; GDPR/compliance gap |
| 7 | Cache invalidation gaps | MEDIUM | Schedule changes don't invalidate milestones; product updates don't invalidate category counts |
| 8 | No database transactions for multi-step operations | MEDIUM | Partial updates possible on failure between multiple db.execute() calls |
| 9 | Inconsistent pagination patterns | LOW | Some use page+page_size, others limit+offset, some have none |
| 10 | No OpenAPI documentation | LOW | Missing endpoint descriptions, example schemas, auth docs, error codes |
| # | Feature | Priority | Description | Value |
|---|---|---|---|---|
| D-01 | Before/After Comparison Slider | HIGH | Split-screen slider showing current room photo vs. AI-generated design | Core visual selling point; high-impact, low-effort (1 week) |
| D-02 | Design Version History | HIGH | Git-like branching: save checkpoints, compare versions, rollback, merge alternate designs | Prevents design loss; enables experimentation |
| D-03 | Material Swapping in 3D Editor | HIGH | Click any surface in 3D view -> browse material options -> see real-time preview | Core design workflow; currently missing from editor |
| D-04 | Client Presentation Mode | HIGH | Slide-deck walkthrough with per-room renders, material callouts, pricing, annotations | Essential for designer-client meetings |
| D-05 | Custom Furniture Designer | MEDIUM | Parametric design: specify wardrobe dimensions, internal layout, material, hardware | Unique differentiator for carpentry market |
| D-06 | Ceiling Design Module | MEDIUM | False ceiling patterns (cove, coffered, tray, POP), integrated lighting channels, AC vents | Missing entire design category |
| D-07 | Kitchen & Bathroom Specifics | MEDIUM | Counter height, chimney placement, wet/dry zone demarcation, fixture positioning | High-value room-specific tools |
| D-08 | Mood Board Builder | MEDIUM | Drag-and-drop from curated library + Pinterest import + custom uploads | Style exploration; client alignment tool |
| D-09 | 360-Degree Panoramic Renders | LOW | Shareable panoramic images per room; embeddable viewer | Marketing and sharing value |
| D-10 | Reference Project Gallery | LOW | Browse completed projects filtered by style, budget, city, room type | Inspiration and trust building |
| # | Feature | Priority | Description | Value |
|---|---|---|---|---|
| E-01 | Structural Analysis Module | CRITICAL | Load-bearing wall detection, modification feasibility, floor load analysis | Safety-critical; blocks wall modification features |
| E-02 | Fire Safety Module | HIGH | Smoke detector placement, fire ratings, escape routes, extinguisher specs | Compliance requirement |
| E-03 | Acoustic Design Module | MEDIUM | STC/IIC ratings, home theater layout, noise isolation, material selection | Premium feature for high-end projects |
| E-04 | MEP Drawing Generation | MEDIUM | Convert MEP calculations into actual DXF/PDF layout drawings (conduit routing, pipe routing) | Gap between calculation and deliverable |
| E-05 | Waterproofing Specification | MEDIUM | Wet area identification, membrane layers, upturn heights, testing protocols | Critical for bathroom/kitchen projects |
| E-06 | Gas Line Planning | LOW | Gas pipe routing, regulator placement, safety valve positions | Regional requirement (India, Middle East) |
| # | Feature | Priority | Description | Value |
|---|---|---|---|---|
| B-01 | Retailer API Integrations | HIGH | Live pricing + inventory from Amazon, IKEA, Home Depot, local retailers | Core procurement value proposition |
| B-02 | Product Compatibility Checking | HIGH | Flag incompatible combinations (heavy countertop on weak cabinet, mismatched valve rough-in) | Prevents costly errors |
| B-03 | AI Chatbot / Copilot | HIGH | "What tile for a high-traffic hallway under $3/sqft?" -- conversational product discovery | Reduces barrier for non-technical users |
| B-04 | Bulk Product Import | MEDIUM | CSV/Excel bulk upload for vendor product catalogs with validation | Scales catalog quickly |
| B-05 | Historical Price Tracking | MEDIUM | Price trends over time; advise on optimal purchase timing | Saves money for homeowners |
| B-06 | Material Usage Tracking | MEDIUM | Track materials used vs. remaining vs. wasted per project | Core waste reduction value proposition |
| B-07 | Returns & Defect Management | MEDIUM | Photo defect -> raise claim -> track resolution -> arrange replacement | End-to-end procurement lifecycle |
| B-08 | Alternative Product Suggestions | MEDIUM | For every BOM item, show 2-3 alternatives at different price points | Budget flexibility |
| B-09 | Delivery Route Optimization | LOW | Multi-stop delivery planning for material dispatch | Cost reduction for logistics |
| B-10 | Offcut Marketplace Enhancements | LOW | Pricing, distance calculation, quality grading for leftover materials | Waste reduction ecosystem |
| # | Feature | Priority | Description | Value |
|---|---|---|---|---|
| P-01 | Delay Auto-Cascade | HIGH | When task X delays by N days, automatically update all downstream dependent tasks | Prevents schedule fiction; shows real impact |
| P-02 | Workforce Scheduling Calendar | HIGH | Calendar-based crew scheduling, multi-project juggling, trade dependency visualization | Essential for contractor coordination |
| P-03 | Progress Photo Geotagging | MEDIUM | Geotagged, timestamped photos mapped to specific tasks and floor plan locations | Verification and accountability |
| P-04 | Issue Pinning on Floor Plan | MEDIUM | Pin issues/snags to specific locations on the floor plan with photos | Spatial context for defect tracking |
| P-05 | Weather Impact on Schedule | LOW | Factor seasonal weather patterns for exterior work scheduling | More realistic timelines |
| P-06 | Proposal Generation | MEDIUM | Auto-generate professional proposals with renders, specs, costs, timeline, T&Cs | Designer-client workflow essential |
| P-07 | Shareable Project Links | MEDIUM | Share specific views with family/advisors without requiring login | Collaboration beyond registered users |
| P-08 | E-Signature Integration | MEDIUM | Digital approval workflow with legally binding signatures | Replaces paper-based approvals |
| # | Feature | Priority | Description | Value |
|---|---|---|---|---|
| I-01 | Mobile App | CRITICAL | React Native / Flutter for site teams: photo capture, AR, daily logs, approvals | Cannot do site work from desktop |
| I-02 | MFA / Two-Factor Authentication | HIGH | TOTP or SMS-based second factor | Security requirement for production |
| I-03 | Auto-Save | HIGH | Periodic auto-save for all forms and design changes | Prevents data loss |
| I-04 | Offline Mode | HIGH | Service worker + IndexedDB for site use without connectivity | Construction sites have poor connectivity |
| I-05 | GDPR Data Export | HIGH | "Download My Data" feature exporting all user data in open formats | Legal requirement in EU |
| I-06 | API Gateway | HIGH | Rate limiting, circuit breaking, unified auth at gateway level | Production readiness |
| I-07 | Feature Flag System | MEDIUM | Toggle features per deployment/user/tenant | Safe rollouts, A/B testing |
| I-08 | Event Bus (NATS/RabbitMQ) | MEDIUM | Replace fire-and-forget HTTP with guaranteed async event delivery | Reliability for job dispatch |
| I-09 | Desktop App | LOW | Electron/Tauri for heavy 3D design work, CAD integration | Power user segment |
| I-10 | Multi-Language UI | MEDIUM | react-intl / next-intl with translation files for 5+ languages | Global expansion |
| # | Feature | Priority | Description | Value |
|---|---|---|---|---|
| C-01 | Permit Management | HIGH | Detect required permits, auto-generate application drawings, track status | Legal compliance |
| C-02 | Vastu/Feng Shui Mode | MEDIUM | Optional layout recommendations based on traditional principles | India/Asia market requirement |
| C-03 | Climate-Specific Design | MEDIUM | Hot-humid, cold, tropical, coastal design recommendations | Global applicability |
| C-04 | RTL Support | MEDIUM | Right-to-left layout for Arabic, Hebrew UI | Middle East expansion |
| C-05 | HOA/Society Rules | LOW | Work hour restrictions, material movement limits, NOC generation | Apartment renovation market |
| C-06 | Safety Protocols | LOW | Site safety checklists, MSDS access, incident reporting | Worker safety |
| # | Feature | Priority | Description | Value |
|---|---|---|---|---|
| A-01 | AI Copilot / Chat Interface | HIGH | Natural language interface for design questions, product discovery, project guidance | Accessibility for non-technical users |
| A-02 | Progress Monitoring | MEDIUM | Compare site photos against design renders to estimate completion % | Automated project tracking |
| A-03 | Material Mood Generation | MEDIUM | AI generates cohesive material palettes (tiles + paint + countertop + backsplash) | Design coherence tool |
| A-04 | Price Forecasting | LOW | Predict material price trends to advise purchase timing | Cost optimization |
| A-05 | Contractor Reliability Scoring | LOW | Predict likelihood of delays based on history and current workload | Better contractor matching |
| Item | Type | Effort |
|---|---|---|
| Remove secrets from version control | Security | 2 days |
| Fix Stripe webhook bypass | Security | 1 hour |
| Add authorization to media service | Security | 1 day |
| Add Error Boundaries to frontend | UI/UX | 1 day |
Replace confirm() with ConfirmDialog |
UI/UX | 1 day |
| Fix SQL injection in catalogue service | Security | 1 hour |
| Add UUID validation for media_id | Security | 1 hour |
| Add form validation across the app | UI/UX | 2 days |
| Add K8s NetworkPolicies | Infra | 1 day |
| Add securityContext to K8s | Infra | 0.5 day |
| Item | Type | Effort |
|---|---|---|
| Before/After comparison slider | Feature | 1 week |
| Breadcrumb navigation | UI/UX | 2 days |
| Real upload progress tracking | UI/UX | 2 days |
| Standardized toast notifications | UI/UX | 1 day |
| Standardized error handling across services | Backend | 3 days |
| Add request ID correlation tracking | Backend | 2 days |
| Add rate limiting to all services | Backend | 2 days |
| Database indexes on foreign keys | Database | 0.5 day |
| CI/CD security scanning | Infra | 1 day |
| Onboarding flow for new users | UI/UX | 3 days |
| Item | Type | Effort |
|---|---|---|
| Structural Analysis Module | Feature | 6-8 weeks |
| Design version history | Feature | 4-6 weeks |
| Material swapping in 3D editor | Feature | 2-3 weeks |
| Client presentation mode | Feature | 2-3 weeks |
| Retailer API integrations | Feature | 8-12 weeks |
| Mobile app (MVP) | Feature | 12-16 weeks |
| AI copilot / chat interface | Feature | 4-6 weeks |
| Permit management | Feature | 4-6 weeks |
| MFA / two-factor authentication | Feature | 1-2 weeks |
| Auto-save | Feature | 1-2 weeks |
| GDPR data export | Feature | 1-2 weeks |
| Item | Type | Effort |
|---|---|---|
| Fire safety module | Feature | 4 weeks |
| Acoustic design module | Feature | 4 weeks |
| Kitchen/bathroom specific tools | Feature | 4-6 weeks |
| Custom furniture designer | Feature | 6-8 weeks |
| Multi-language UI (5+ languages) | Feature | 4-6 weeks |
| RTL support | Feature | 2-3 weeks |
| Vastu/Feng Shui mode | Feature | 2 weeks |
| Desktop app | Feature | 12+ weeks |
| Offline mode | Feature | 4-6 weeks |
| Historical price tracking | Feature | 2-3 weeks |
| Metric | Count |
|---|---|
| Total security findings | 16 (7 CRITICAL, 9 HIGH) |
| Total code quality findings | 88 |
| Total UI/UX issues | 25 |
| Total backend API errors | 47 |
| Requirements implemented | 125 / 307 (41%) |
| Requirements partially done | 80 / 307 (26%) |
| Requirements not started | 102 / 307 (33%) |
| Desired new features | 51 |
| Test files across entire project | 3 |
| Source files | 407 |
| Lines of code | ~82,746 |
| Microservices | 11 |
| ML pipelines | 5 |
- Ambitious and coherent vision -- end-to-end pipeline from photo to digital twin
- Strong AI/ML integration -- SAM2, depth estimation, LangGraph agents, multi-provider VLM
- Well-decomposed microservices -- clean bounded contexts, shared package pattern
- Rich feature set already built -- 45 developed features including 3D editor, AR/VR, BOM, MEP, Gantt, collaboration
- Modern tech stack -- Next.js 15, React 19, FastAPI, Drizzle ORM, WebXR
- Building code dataset -- structured multi-jurisdiction compliance data
- Security hardening -- secrets, auth bypass, webhook bypass, SQL injection
- Testing -- 3 test files for 407 source files is a ticking time bomb
- Error handling -- 41+ silent exception blocks masking bugs
- Mobile app -- site teams, photo capture, AR measurement all require mobile
- Structural analysis -- safety-critical; can't recommend wall modifications without it
- AI Copilot -- "Design my kitchen in modern style under $5000" as a conversation
- Before/After slider + Presentation mode -- visual selling tools
- Live retailer pricing -- real-time procurement from actual vendors
- Design version history -- git for interior design
- Mobile app with offline -- site management without WiFi
- Structural + fire safety -- engineering completeness builds trust
End of Comprehensive Code Audit Report -- Part 2: Missing Features, Errors, UI/UX Issues & Desired Features Total findings across Part 1 + Part 2: 278 items catalogued with file paths, line numbers, severity ratings, and specific recommendations.