Files
lcbp3/specs/200-fullstacks/236-unified-ocr-architecture/plan.md
T
admin 7e8f4859cd
CI / CD Pipeline / build (push) Failing after 6m24s
CI / CD Pipeline / deploy (push) Has been skipped
feat(ai): add ADR-036 unified OCR architecture and frontend test coverage
- Add ADR-036 unified OCR architecture (typhoon-ocr via Ollama)
- Extend AI execution profiles for OCR sandbox configuration
- Add comprehensive frontend test coverage (components, hooks, services)
- Add backend test coverage for document-numbering services
- Update OCR sidecar with typhoon-ocr integration
- Add AI policy service and execution profile management
- Update AGENTS.md and architecture documentation
2026-06-14 06:34:07 +07:00

7.9 KiB

// File: specs/200-fullstacks/236-unified-ocr-architecture/plan.md // Change Log: // - 2026-06-13: Initial implementation plan for Unified AI Model Architecture

Implementation Plan: Unified AI Model Architecture — Sandbox-Production Parity

Branch: 236-unified-ocr-architecture | Date: 2026-06-13 | Spec: spec.md Input: Feature specification from /specs/200-fullstacks/236-unified-ocr-architecture/spec.md

Note: This template is filled in by the /speckit.plan command. See .specify/templates/commands/plan.md for the execution workflow.

Summary

Enhance the existing Profile-Only Parameter Governance (AiPolicyService + ai_execution_profiles) to add write/apply path for sandbox testing and production parameter management. The feature introduces a sandbox draft store (ai_sandbox_profiles) that mirrors the production store, allowing admins to test parameters for both np-dms-ai and np-dms-ocr models before applying to production. Key technical approach: extend existing AiPolicyService with sandbox methods, add canonical_model column to distinguish models, implement dual-model snapshot for OCR+LLM jobs, and enforce security guardrails (Idempotency-Key, CASL, validation). Model names are updated from typhoon2.5-np-dms/typhoon-np-dms-ocr to np-dms-ai/np-dms-ocr across codebase.

Technical Context

Language/Version: TypeScript 5.7 (Backend: NestJS 11, Frontend: Next.js 16) Primary Dependencies: NestJS, TypeORM, Redis, BullMQ, TanStack Query, React Hook Form, Zod Storage: MariaDB 11.8 (ai_execution_profiles, ai_sandbox_profiles, ai_audit_logs), Redis (cache) Testing: Jest (backend), Vitest + Playwright (frontend) Target Platform: Linux server (QNAP), Windows 10/11 (Desk-5439 OCR sidecar) Project Type: web (fullstack: backend + frontend) Performance Goals: Apply operation <2s, Sandbox test <5s cycle, Cache invalidation <100ms Constraints: ADR-009 (no migrations), ADR-019 (UUID handling), ADR-016 (security), ADR-023/023A (AI boundary) Scale/Scope: 2 models (np-dms-ai, np-dms-ocr), 5 profiles (interactive, standard, quality, deep-analysis, ocr-extract), admin-only feature

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

Gate Status Justification
ADR-009: No TypeORM migrations PASS Schema changes via SQL delta (deltas/2026-06-13-extend-ai-execution-profiles-ocr.sql)
ADR-019: UUID handling PASS No new UUID fields; existing UUID patterns followed
ADR-016: Security PASS CASL guard (system.manage_ai), Idempotency-Key validation, parameter range validation
ADR-023/023A: AI boundary PASS No direct DB/storage access from AI; existing pipeline maintained
ADR-007: Error handling PASS Layered error classification, user-friendly messages
ADR-029: Dynamic Prompts PASS Integration only; no duplication in parameter store
ADR-033: Adaptive OCR Residency PASS keep_alive lazy-loading retained; not frozen in snapshot

Project Structure

Documentation (this feature)

specs/200-fullstacks/236-unified-ocr-architecture/
├── spec.md              # Feature specification
├── plan.md              # This file (/speckit.plan command output)
├── research.md          # Phase 0 output (/speckit.plan command)
├── data-model.md        # Phase 1 output (/speckit.plan command)
├── quickstart.md        # Phase 1 output (/speckit.plan command)
├── contracts/           # Phase 1 output (/speckit.plan command)
│   ├── backend-api.yaml # OpenAPI spec for new endpoints
│   └── frontend-api.yaml # Frontend API service contracts
└── tasks.md             # Phase 2 output (/speckit.tasks command)

Source Code (repository root)

backend/
├── src/
│   ├── modules/
│   │   └── ai/
│   │       ├── entities/
│   │       │   ├── ai-execution-profile.entity.ts      # MODIFY: +canonicalModel, nullable numCtx/maxTokens
│   │       │   └── ai-sandbox-profile.entity.ts        # NEW: draft store
│   │       ├── services/
│   │       │   ├── ai-policy.service.ts                # MODIFY: +sandbox methods, applyProfile
│   │       │   ├── ocr.service.ts                      # MODIFY: +typhoonOptions in OcrDetectionInput
│   │       │   ├── ollama.service.ts                    # MODIFY: update model names
│   │       │   └── sandbox-ocr-engine.service.ts        # KEEP: ephemeral override
│   │       ├── processors/
│   │       │   └── ai-batch.processor.ts               # MODIFY: dual-model snapshot, sandbox draft read
│   │       ├── controllers/
│   │       │   ├── ai.controller.ts                    # MODIFY: apply/test/get endpoints
│   │       │   └── ai-sandbox.controller.ts             # MODIFY: apply endpoint
│   │       ├── dto/
│   │       │   ├── apply-profile.dto.ts                 # NEW: validation DTO
│   │       │   └── apply-result.dto.ts                  # NEW: result DTO
│   │       ├── interfaces/
│   │       │   └── execution-policy.interface.ts        # MODIFY: +ocrSnapshotParams in AiJobPayload
│   │       └── ai.module.ts                             # MODIFY: register new entities/services
│   └── common/
│       └── decorators/
│           └── audit.decorator.ts                      # MODIFY: support APPLY_PROFILE action
└── tests/
    ├── unit/
    │   └── modules/
    │       └── ai/
    │           ├── ai-policy.service.spec.ts            # MODIFY: +sandbox/apply tests
    │           └── ai-batch.processor.spec.ts            # MODIFY: +dual-model snapshot tests
    └── integration/
        └── modules/
            └── ai/
                └── ai-policy.service.integration.spec.ts # NEW: end-to-end apply flow

frontend/
├── lib/
│   ├── services/
│   │   └── admin-ai.service.ts                          # MODIFY: +apply/test/get profile functions
├── components/
│   └── admin/
│       └── ai/
│           ├── OcrSandboxPromptManager.tsx             # MODIFY: +apply runtime params, project/contract selector
│           └── ModelTestingPanel.tsx                    # NEW: unified parameter testing UI
├── app/
│   └── (admin)/
│       └── admin/
│           └── ai/
│               └── page.tsx                             # MODIFY: integrate new testing panel
└── tests/
    ├── unit/
    │   └── services/
    │       └── admin-ai.service.spec.ts                # MODIFY: +apply/test/get tests
    └── e2e/
        └── ai/
            └── parameter-management.spec.ts             # NEW: apply flow E2E tests

specs/03-Data-and-Storage/
└── deltas/
    ├── 2026-06-13-extend-ai-execution-profiles-ocr.sql   # NEW: schema changes
    └── 2026-06-13-extend-ai-execution-profiles-ocr.rollback.sql # NEW: rollback

specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/
└── ocr-sidecar/
    ├── app.py                                            # MODIFY: update model name (if needed)
    └── docker-compose.yml                               # MODIFY: update model name (if needed)

Structure Decision: Web application (Option 2) - This is a fullstack feature extending the existing NestJS backend and Next.js frontend. Backend changes focus on AI module (entities, services, processors, controllers, DTOs). Frontend changes focus on admin AI console components and services. Infrastructure changes limited to OCR sidecar model name updates.

Complexity Tracking

Fill ONLY if Constitution Check has violations that must be justified

No violations detected. All gates passed.