feat/Update_Controllers_to_Allow_for_Premium_Membership
This commit is contained in:
@@ -0,0 +1,825 @@
|
||||
Create and implement a production-safe, local-first AI architecture for JobTracker.
|
||||
|
||||
This is an authorised production infrastructure and application change, but proceed conservatively with inspection, benchmarking, backups, staged rollout and rollback capability.
|
||||
|
||||
Do not guess production connection details. Use only an existing documented SSH host, deployment mechanism or configured environment. Do not scan the network.
|
||||
|
||||
If production access is unavailable, complete all safe repository-side design and implementation work, document the exact access blocker, and stop before inventing credentials or connection details.
|
||||
|
||||
## Objectives
|
||||
|
||||
1. Analyse the actual production machine.
|
||||
2. Identify the best current Ollama model for JobTracker’s real workloads.
|
||||
3. Benchmark suitable candidates rather than selecting solely from published claims.
|
||||
4. Install the selected model.
|
||||
5. Make local Ollama the default production AI provider.
|
||||
6. Make external AI providers secondary fallbacks.
|
||||
7. Keep CVs, job descriptions and email data local whenever practical.
|
||||
8. Introduce durable queuing so AI work does not block web requests.
|
||||
9. Prevent Ollama congestion from hanging the application.
|
||||
10. Provide progress, retry and failure states to users.
|
||||
11. Preserve privacy, tenant isolation and Pro entitlement enforcement.
|
||||
12. Make the deployment observable and safely reversible.
|
||||
|
||||
Do not remove existing models, configuration or external providers without explicit approval. Preserve them for rollback.
|
||||
|
||||
## Existing audit requirements
|
||||
|
||||
Read:
|
||||
|
||||
* All applicable `AGENTS.md` files
|
||||
* Deployment documentation
|
||||
* Docker and Compose configuration
|
||||
* Environment examples
|
||||
* AI-provider configuration
|
||||
* Python/FastAPI AI implementation
|
||||
* ASP.NET AI endpoints and hosted services
|
||||
* Frontend AI workflows
|
||||
* `docs/audits/full-application-audit.md`
|
||||
* `docs/audits/security-threat-model.md`
|
||||
* `docs/audits/audit-remediation-backlog.md`
|
||||
* `docs/audits/verification-log.md`
|
||||
* `docs/plans/post-audit-ux-reliability-program.md`, if present
|
||||
|
||||
Pay particular attention to:
|
||||
|
||||
* JT-005 inert tenant-scoped hosted services
|
||||
* JT-006 document-parser isolation
|
||||
* AI privacy controls
|
||||
* Notification persistence
|
||||
* Pro entitlement enforcement
|
||||
* Strategy Snapshot timeouts
|
||||
* Long-running CV processing
|
||||
* External-provider data exposure
|
||||
* Tenant context inside background jobs
|
||||
|
||||
Do not activate currently inert background workers until tenant resolution, persistent notification handling, AI privacy controls and entitlement enforcement are correct.
|
||||
|
||||
## Phase 1: Read-only production inventory
|
||||
|
||||
Before changing production, gather a sanitised read-only inventory.
|
||||
|
||||
Record:
|
||||
|
||||
### Operating system
|
||||
|
||||
* Distribution and version
|
||||
* Kernel
|
||||
* Uptime
|
||||
* Time zone
|
||||
* Current load
|
||||
* Relevant system limits
|
||||
|
||||
### CPU and memory
|
||||
|
||||
* CPU model
|
||||
* Physical and logical cores
|
||||
* Total and available RAM
|
||||
* Swap size and usage
|
||||
* Memory pressure
|
||||
* Other memory-intensive services
|
||||
|
||||
### GPU
|
||||
|
||||
* Exact GPU model
|
||||
* VRAM
|
||||
* NVIDIA driver
|
||||
* Reported CUDA compatibility
|
||||
* Current GPU processes
|
||||
* Idle and loaded VRAM
|
||||
* Temperature and power state where available
|
||||
* Whether Ollama is actually using the GPU
|
||||
* CPU/GPU layer offloading behaviour
|
||||
|
||||
### Storage
|
||||
|
||||
* Available capacity
|
||||
* Ollama model storage location
|
||||
* Filesystem
|
||||
* Model sizes
|
||||
* Space required for benchmark candidates
|
||||
* Production database and attachment storage
|
||||
* Backup capacity
|
||||
|
||||
Do not expose unrelated filenames or private user data.
|
||||
|
||||
### Ollama
|
||||
|
||||
* Installed version
|
||||
* Installation method
|
||||
* Service manager
|
||||
* Service configuration
|
||||
* Bound address
|
||||
* Existing environment variables
|
||||
* Installed models
|
||||
* Currently loaded models
|
||||
* Current model usage
|
||||
* Existing API clients
|
||||
* Health
|
||||
* Logs relevant to performance or failures
|
||||
|
||||
Do not print secrets or complete prompt contents from production logs.
|
||||
|
||||
### Application deployment
|
||||
|
||||
* Running JobTracker services
|
||||
* Docker/container versions
|
||||
* Network topology
|
||||
* Ollama connectivity
|
||||
* Reverse-proxy timeouts
|
||||
* AI service configuration
|
||||
* Current external provider order
|
||||
* Current model selections
|
||||
* Background workers
|
||||
* Queue implementation, if any
|
||||
* Health checks
|
||||
* Restart behaviour
|
||||
* Resource limits
|
||||
* Monitoring
|
||||
|
||||
Confirm whether the remembered specification of 32 GB RAM and GTX 1060 6 GB is accurate. Use measured production data as the source of truth.
|
||||
|
||||
Create:
|
||||
|
||||
`docs/production/production-ai-hardware-assessment.md`
|
||||
|
||||
Do not include hostnames, public IP addresses, credentials, tokens or other sensitive infrastructure identifiers.
|
||||
|
||||
## Phase 2: Production safety and backup
|
||||
|
||||
Before changing anything:
|
||||
|
||||
1. Record the current production configuration.
|
||||
2. Back up affected non-secret configuration safely.
|
||||
3. Record current Ollama and external-provider defaults.
|
||||
4. Record currently installed model names and digests.
|
||||
5. Confirm sufficient free disk space.
|
||||
6. Define rollback commands.
|
||||
7. Confirm how services will be restarted.
|
||||
8. Identify expected interruption.
|
||||
9. Verify that application and database backups are not affected.
|
||||
10. Confirm Ollama is not publicly exposed.
|
||||
|
||||
Ollama should be reachable only through:
|
||||
|
||||
* Localhost
|
||||
* A private container network
|
||||
* An explicitly authorised private service network
|
||||
|
||||
It must not receive an unauthenticated public Traefik route.
|
||||
|
||||
Do not include secret values in the backup report.
|
||||
|
||||
Create:
|
||||
|
||||
`docs/production/production-ai-rollout-and-rollback.md`
|
||||
|
||||
## Phase 3: Workload inventory and evaluation set
|
||||
|
||||
Inventory every JobTracker AI task.
|
||||
|
||||
Likely tasks include, but are not limited to:
|
||||
|
||||
* CV text normalisation
|
||||
* Career Profile extraction
|
||||
* Conservative CV merge suggestions
|
||||
* Job-description summarisation
|
||||
* Job keyword and phrase extraction
|
||||
* Skill matching
|
||||
* Missing-skill identification
|
||||
* Application strategy generation
|
||||
* Strategy Snapshot
|
||||
* CV tailoring suggestions
|
||||
* Cover-letter drafting
|
||||
* Follow-up drafting
|
||||
* Email classification
|
||||
* Recruitment-message detection
|
||||
* Interview preparation
|
||||
* Writing improvement
|
||||
* Grammar correction
|
||||
* English and Norwegian content
|
||||
* Structured JSON generation
|
||||
|
||||
For each task record:
|
||||
|
||||
* Input type
|
||||
* Typical input size
|
||||
* Maximum expected input size
|
||||
* Required output format
|
||||
* Structured-output requirements
|
||||
* Language
|
||||
* Latency target
|
||||
* Quality importance
|
||||
* Privacy sensitivity
|
||||
* Whether external fallback is permitted
|
||||
* Whether it is interactive or background work
|
||||
* Whether deterministic code should replace AI
|
||||
* Current provider/model
|
||||
* Pro entitlement requirement
|
||||
|
||||
Do not use AI for deterministic operations that are more reliably handled with code.
|
||||
|
||||
For example, Norwegian/English stop-word removal and basic keyword cleanup should remain deterministic even when an AI model contributes semantic phrase extraction.
|
||||
|
||||
Create a sanitised evaluation dataset using synthetic or redacted data.
|
||||
|
||||
The evaluation set must cover:
|
||||
|
||||
* English CV
|
||||
* Norwegian CV
|
||||
* Mixed-language CV
|
||||
* English job advert
|
||||
* Norwegian job advert
|
||||
* Noisy imported job advert
|
||||
* Technology-heavy role
|
||||
* Sparse role
|
||||
* Email classification
|
||||
* Follow-up draft
|
||||
* Strategy Snapshot
|
||||
* Strict JSON response
|
||||
* Malformed or adversarial document text
|
||||
* Prompt-injection-style text inside a job advert or email
|
||||
* Long input
|
||||
* Empty and invalid input
|
||||
|
||||
Do not place real CV or email contents in the repository.
|
||||
|
||||
The previously authorised CV may be used locally for final local-only validation:
|
||||
|
||||
`F:\Documents\Work\CV and stuff\New CV\Connor Babbington - CV -English-.pdf`
|
||||
|
||||
Restrictions:
|
||||
|
||||
* Never commit it.
|
||||
* Never send it to an external AI provider.
|
||||
* Never expose its contents in reports.
|
||||
* Remove temporary copies.
|
||||
* Use synthetic fixtures for repeatable automated tests.
|
||||
|
||||
## Phase 4: Candidate model selection
|
||||
|
||||
Do not assume that the largest model is best for production.
|
||||
|
||||
Select candidates appropriate to the measured hardware and JobTracker workloads.
|
||||
|
||||
At minimum, consider the current locally available variants of:
|
||||
|
||||
* `qwen3.5:4b`
|
||||
* `qwen3:4b`
|
||||
* `gemma3:4b`
|
||||
* The currently installed production model
|
||||
|
||||
If measured hardware and disk space permit, optionally benchmark:
|
||||
|
||||
* `qwen3:8b`
|
||||
* `qwen3.5:9b`
|
||||
|
||||
Do not download very large models that clearly cannot run acceptably on the measured machine.
|
||||
|
||||
Do not select cloud-labelled Ollama models. The selected primary must execute locally.
|
||||
|
||||
For every candidate, verify:
|
||||
|
||||
* Exact tag
|
||||
* Download size
|
||||
* Quantisation
|
||||
* Licence and hosted-use implications
|
||||
* Required Ollama version
|
||||
* Tool/structured-output compatibility
|
||||
* Context requirements
|
||||
* VRAM residency
|
||||
* CPU offloading
|
||||
* Peak system RAM
|
||||
* Peak VRAM
|
||||
* Load time
|
||||
* Time to first token
|
||||
* Tokens per second
|
||||
* Total latency
|
||||
* Output quality
|
||||
* JSON validity
|
||||
* Instruction adherence
|
||||
* English quality
|
||||
* Norwegian quality
|
||||
* Hallucination rate in the evaluation set
|
||||
* Behaviour on prompt-injection-style content
|
||||
* Failure behaviour
|
||||
* Stability over repeated requests
|
||||
|
||||
Do not rely only on synthetic benchmark scores published by model authors.
|
||||
|
||||
## Phase 5: Context and performance tuning
|
||||
|
||||
Do not use the model’s advertised maximum context automatically.
|
||||
|
||||
Benchmark practical context sizes such as:
|
||||
|
||||
* 4K
|
||||
* 8K
|
||||
* 16K only if measured resources permit
|
||||
|
||||
Select the smallest context that reliably supports JobTracker tasks.
|
||||
|
||||
Measure the effect of:
|
||||
|
||||
* Context size
|
||||
* Prompt length
|
||||
* Output-token limit
|
||||
* Thinking/reasoning mode
|
||||
* Temperature
|
||||
* Structured output
|
||||
* K/V cache type
|
||||
* GPU offloading
|
||||
* Model keep-alive
|
||||
* Parallel requests
|
||||
|
||||
Prioritise reliable latency and bounded memory over theoretical maximum context.
|
||||
|
||||
For a single 6 GB GPU, start evaluation conservatively with:
|
||||
|
||||
* One loaded model
|
||||
* One parallel inference
|
||||
* Bounded Ollama queue
|
||||
* Bounded application queue
|
||||
* Limited context
|
||||
* Model kept warm only when resource usage is acceptable
|
||||
|
||||
Treat these as benchmark starting points, not unquestionable final values:
|
||||
|
||||
```text
|
||||
OLLAMA_MAX_LOADED_MODELS=1
|
||||
OLLAMA_NUM_PARALLEL=1
|
||||
OLLAMA_MAX_QUEUE=<measured bounded value>
|
||||
OLLAMA_KEEP_ALIVE=<measured duration>
|
||||
```
|
||||
|
||||
Evaluate `OLLAMA_KV_CACHE_TYPE=q8_0` only if supported and beneficial. Record any measured quality or memory difference.
|
||||
|
||||
Do not enable options unsupported by the installed GPU/runtime merely because they exist in documentation.
|
||||
|
||||
## Phase 6: Model decision
|
||||
|
||||
Create:
|
||||
|
||||
`docs/production/ollama-model-benchmark.md`
|
||||
|
||||
Include a table containing:
|
||||
|
||||
* Candidate
|
||||
* Size
|
||||
* Quantisation
|
||||
* VRAM
|
||||
* RAM
|
||||
* GPU offload
|
||||
* Context
|
||||
* Load time
|
||||
* First-token latency
|
||||
* Total latency
|
||||
* Tokens/second
|
||||
* Quality score by JobTracker task
|
||||
* JSON success rate
|
||||
* Norwegian quality
|
||||
* Failure rate
|
||||
* Licence notes
|
||||
* Recommendation
|
||||
|
||||
Select:
|
||||
|
||||
1. Primary local model
|
||||
2. Optional lightweight fallback local model
|
||||
3. Tasks that should use deterministic processing
|
||||
4. Tasks that genuinely require external fallback
|
||||
|
||||
The selected default must be based on measured JobTracker performance.
|
||||
|
||||
If the remembered GTX 1060 6 GB specification is confirmed, use `qwen3.5:4b` as the initial leading candidate, but select another model if evidence shows it performs better.
|
||||
|
||||
Do not choose `qwen3.5:9b` merely because it is larger if GPU offloading makes it too slow or unstable.
|
||||
|
||||
## Phase 7: Local-first provider architecture
|
||||
|
||||
Refactor AI provider selection into one explicit, testable policy.
|
||||
|
||||
Provider priority should normally be:
|
||||
|
||||
1. Deterministic local processing where appropriate
|
||||
2. Primary local Ollama model
|
||||
3. Optional secondary local model
|
||||
4. Configured external provider only when policy permits
|
||||
5. Clear failure with retry option
|
||||
|
||||
Do not scatter provider selection throughout controllers and components.
|
||||
|
||||
Create a central AI routing policy that considers:
|
||||
|
||||
* Task type
|
||||
* Required capability
|
||||
* Privacy classification
|
||||
* Pro entitlement
|
||||
* User/admin external-AI preference
|
||||
* Local health
|
||||
* Queue depth
|
||||
* Deadline
|
||||
* Retry count
|
||||
* Previous provider failure
|
||||
* External-provider availability
|
||||
* Cost/budget controls
|
||||
|
||||
### Privacy rules
|
||||
|
||||
Never send the following externally without an explicit server-side policy and appropriate user permission:
|
||||
|
||||
* Full CV
|
||||
* Career Profile
|
||||
* Email body
|
||||
* Attachments
|
||||
* Provider tokens
|
||||
* Private notes
|
||||
* Contact information
|
||||
* Personally identifying application data
|
||||
|
||||
Where external fallback is allowed:
|
||||
|
||||
* Send only the minimum required data.
|
||||
* Record which provider handled the request.
|
||||
* Make fallback visible in administrative diagnostics.
|
||||
* Respect a `local only` user or administrator setting.
|
||||
* Never silently override an external-AI opt-out.
|
||||
* Do not expose provider secrets to the browser.
|
||||
* Apply Pro entitlement before work is queued.
|
||||
|
||||
If an external provider is unavailable or prohibited, return a useful queued/failed state rather than hanging.
|
||||
|
||||
## Phase 8: Durable AI queue
|
||||
|
||||
Do not keep long-running AI work inside the original HTTP request.
|
||||
|
||||
Implement a persistent queue using the project’s existing infrastructure where practical.
|
||||
|
||||
Before introducing a new queue library, evaluate:
|
||||
|
||||
* Existing database-backed job infrastructure
|
||||
* Existing PostgreSQL/MariaDB capabilities
|
||||
* Existing Redis deployment
|
||||
* Existing hosted workers
|
||||
* Existing outbox patterns
|
||||
|
||||
Choose the smallest reliable design that survives process restart.
|
||||
|
||||
### Required job states
|
||||
|
||||
Use explicit states such as:
|
||||
|
||||
* Queued
|
||||
* Running
|
||||
* Succeeded
|
||||
* Failed
|
||||
* Cancelled
|
||||
* WaitingForRetry
|
||||
* WaitingForExternalFallback
|
||||
|
||||
Persist:
|
||||
|
||||
* Operation ID
|
||||
* Tenant/user ID
|
||||
* Task type
|
||||
* Entitlement decision
|
||||
* Privacy/fallback policy
|
||||
* Sanitised request metadata
|
||||
* Provider selected
|
||||
* Model
|
||||
* Attempt count
|
||||
* Creation/start/completion timestamps
|
||||
* Progress stage
|
||||
* Failure category
|
||||
* Result reference
|
||||
* Idempotency key
|
||||
|
||||
Do not store unnecessary raw CV or email contents in queue records.
|
||||
|
||||
### API behaviour
|
||||
|
||||
Long-running endpoints should:
|
||||
|
||||
1. Validate authorization, tenant ownership and Pro entitlement.
|
||||
2. Create an idempotent operation.
|
||||
3. Return `202 Accepted`.
|
||||
4. Return a stable operation ID and status URL.
|
||||
5. Let the frontend poll or receive safe push updates.
|
||||
6. Permit safe retry where appropriate.
|
||||
7. Avoid duplicate work from double clicks.
|
||||
8. Survive browser refresh and application restart.
|
||||
|
||||
### Worker behaviour
|
||||
|
||||
Workers must:
|
||||
|
||||
* Resolve tenant context explicitly.
|
||||
* Avoid the tenant-filter failure identified in JT-005.
|
||||
* Re-check entitlement and cancellation before expensive work.
|
||||
* Claim jobs atomically.
|
||||
* Use leases/heartbeats so abandoned jobs recover.
|
||||
* Enforce per-task timeout.
|
||||
* Use bounded retries with jitter.
|
||||
* Distinguish retryable and permanent failures.
|
||||
* Avoid processing one job twice.
|
||||
* Persist results transactionally.
|
||||
* Generate persistent user notifications.
|
||||
* Avoid logging raw private content.
|
||||
* Shut down gracefully.
|
||||
* Recover in-progress work after restart.
|
||||
|
||||
## Phase 9: Backpressure and Ollama congestion
|
||||
|
||||
The application queue must protect Ollama rather than forwarding unlimited parallel requests.
|
||||
|
||||
Implement:
|
||||
|
||||
* Configurable worker concurrency
|
||||
* Per-model concurrency
|
||||
* Global local-AI concurrency
|
||||
* Bounded queue capacity
|
||||
* Request prioritisation
|
||||
* Load shedding
|
||||
* Queue-age limit
|
||||
* Operation deadline
|
||||
* Circuit breaker
|
||||
* Health checks
|
||||
* Retry-after guidance
|
||||
* Cancellation
|
||||
* Graceful degradation
|
||||
|
||||
Suggested priority order:
|
||||
|
||||
1. Interactive user-requested operations
|
||||
2. User-visible CV/job analysis
|
||||
3. Email/follow-up drafting
|
||||
4. Scheduled enrichment
|
||||
5. Bulk/background regeneration
|
||||
|
||||
Do not let scheduled jobs starve interactive work.
|
||||
|
||||
For likely single-GPU deployment, begin with one Ollama inference at a time unless benchmarks demonstrate safe parallelism.
|
||||
|
||||
Do not allow both Ollama’s internal queue and the application queue to grow without effective bounds.
|
||||
|
||||
If Ollama returns 503, times out, crashes, unloads unexpectedly or becomes unhealthy:
|
||||
|
||||
1. Record the local attempt.
|
||||
2. Apply bounded local retry where appropriate.
|
||||
3. Evaluate the external-fallback policy.
|
||||
4. Use external fallback only if permitted.
|
||||
5. Otherwise leave a clear recoverable failure.
|
||||
6. Never leave the frontend spinner running indefinitely.
|
||||
|
||||
## Phase 10: External fallback behaviour
|
||||
|
||||
External providers are secondary, not peers selected arbitrarily.
|
||||
|
||||
Define fallback triggers such as:
|
||||
|
||||
* Ollama unavailable
|
||||
* Local circuit open
|
||||
* Local operation exceeds its deadline
|
||||
* Local model lacks a required capability
|
||||
* Repeated schema-validation failure
|
||||
* Explicit user request for an allowed external-quality operation
|
||||
|
||||
Do not trigger external fallback merely because the local queue is briefly busy unless the configured queue deadline would be exceeded and privacy policy permits it.
|
||||
|
||||
Before external fallback:
|
||||
|
||||
* Re-check user consent
|
||||
* Re-check Pro entitlement
|
||||
* Re-check task sensitivity
|
||||
* Minimise the payload
|
||||
* Apply cost limits
|
||||
* Record the reason
|
||||
* Avoid duplicate local and external completion
|
||||
|
||||
Never allow both providers to complete and charge for the same operation without an explicit race strategy and deduplication.
|
||||
|
||||
Make provider preference configurable by administrators:
|
||||
|
||||
* Local only
|
||||
* Local first with approved fallback
|
||||
* External only for specifically allowed tasks
|
||||
|
||||
Default production behaviour should be local first.
|
||||
|
||||
## Phase 11: Frontend queued-operation experience
|
||||
|
||||
Replace indefinite spinners with explicit durable operation states.
|
||||
|
||||
For Strategy Snapshot, CV processing, job analysis and other applicable AI actions, show:
|
||||
|
||||
* Queued
|
||||
* Processing locally
|
||||
* Waiting
|
||||
* Retrying
|
||||
* Using approved fallback where disclosure is appropriate
|
||||
* Completed
|
||||
* Failed
|
||||
* Cancelled
|
||||
|
||||
Provide:
|
||||
|
||||
* Clear status
|
||||
* Safe page refresh
|
||||
* Navigation away without losing the operation
|
||||
* Notification on completion
|
||||
* Retry action
|
||||
* Cancel action where supported
|
||||
* No duplicate submission
|
||||
* Useful error text
|
||||
* No exposure of internal prompts or secrets
|
||||
|
||||
Do not display an unreliable queue position as an exact promise.
|
||||
|
||||
Free users must receive the established Pro locked state before an AI job is created.
|
||||
|
||||
## Phase 12: Observability
|
||||
|
||||
Add privacy-safe telemetry for:
|
||||
|
||||
* Queue depth
|
||||
* Oldest queued job age
|
||||
* Time spent queued
|
||||
* Processing duration
|
||||
* First-token latency where available
|
||||
* Tokens/second
|
||||
* Prompt and completion token estimates
|
||||
* Model load duration
|
||||
* GPU/RAM usage where safely obtainable
|
||||
* Success/failure rate
|
||||
* Timeout rate
|
||||
* Retry rate
|
||||
* Cancellation rate
|
||||
* External-fallback rate
|
||||
* Provider/model usage
|
||||
* Schema-validation failures
|
||||
* Jobs recovered after restart
|
||||
|
||||
Add health signals for:
|
||||
|
||||
* Ollama reachable
|
||||
* Selected model installed
|
||||
* Model warm/cold
|
||||
* Queue worker running
|
||||
* Queue stalled
|
||||
* External provider configured
|
||||
* Circuit state
|
||||
|
||||
Do not include CV, job-description or email contents in metrics.
|
||||
|
||||
Create an operational runbook:
|
||||
|
||||
`docs/production/local-ai-operations-runbook.md`
|
||||
|
||||
Include:
|
||||
|
||||
* Health checks
|
||||
* Queue inspection
|
||||
* Model status
|
||||
* Safe restart
|
||||
* Draining workers
|
||||
* Cancelling stuck jobs
|
||||
* Circuit reset
|
||||
* Rollback
|
||||
* External fallback disablement
|
||||
* Disk management
|
||||
* Model update procedure
|
||||
* Incident diagnostics
|
||||
|
||||
## Phase 13: Installation and staged production rollout
|
||||
|
||||
Only after inventory and benchmarks:
|
||||
|
||||
1. Pull the selected model.
|
||||
2. Verify its digest and size.
|
||||
3. Confirm sufficient disk remains.
|
||||
4. Configure conservative Ollama limits.
|
||||
5. Keep the previous model installed.
|
||||
6. Update the application’s production model default.
|
||||
7. Configure local-first routing.
|
||||
8. Deploy durable queue changes.
|
||||
9. Apply required database migrations safely.
|
||||
10. Start one worker.
|
||||
11. Run health checks.
|
||||
12. Run synthetic smoke tests.
|
||||
13. Run local-only testing with the authorised CV if safe.
|
||||
14. Verify no external provider received that CV.
|
||||
15. Verify Free/Pro entitlement.
|
||||
16. Verify tenant isolation.
|
||||
17. Verify restart recovery.
|
||||
18. Verify timeout and fallback behaviour.
|
||||
19. Observe resource usage.
|
||||
20. Expand traffic only after successful validation.
|
||||
|
||||
Do not delete the old model after rollout.
|
||||
|
||||
If production becomes unhealthy:
|
||||
|
||||
* Stop accepting new AI jobs.
|
||||
* Drain or preserve queued work.
|
||||
* Roll back application configuration.
|
||||
* Restore the prior model default.
|
||||
* Restart affected services safely.
|
||||
* Verify the previous path.
|
||||
* Preserve diagnostic evidence.
|
||||
|
||||
## Phase 14: Validation matrix
|
||||
|
||||
Create:
|
||||
|
||||
`docs/production/production-ai-validation.md`
|
||||
|
||||
Test:
|
||||
|
||||
* Local keyword extraction
|
||||
* Norwegian job analysis
|
||||
* English job analysis
|
||||
* CV extraction
|
||||
* Strategy Snapshot
|
||||
* CV suggestion
|
||||
* Email classification
|
||||
* Follow-up draft
|
||||
* Strict JSON output
|
||||
* Prompt-injection-style input
|
||||
* Concurrent submissions
|
||||
* Double click
|
||||
* Queue congestion
|
||||
* Ollama offline
|
||||
* Ollama timeout
|
||||
* Ollama restart
|
||||
* Application restart
|
||||
* Worker restart
|
||||
* External fallback allowed
|
||||
* External fallback prohibited
|
||||
* External provider unavailable
|
||||
* User cancellation
|
||||
* Free user
|
||||
* Pro user
|
||||
* Two different tenants
|
||||
* Browser refresh
|
||||
* Notification delivery
|
||||
* Failed result retry
|
||||
|
||||
Classify each as:
|
||||
|
||||
* Passed locally
|
||||
* Passed with approved fallback
|
||||
* Failed
|
||||
* Blocked
|
||||
* Mock-tested
|
||||
* Not applicable
|
||||
|
||||
## Tests
|
||||
|
||||
Add or update:
|
||||
|
||||
* AI-routing unit tests
|
||||
* Entitlement tests
|
||||
* Privacy-policy tests
|
||||
* Provider-fallback tests
|
||||
* Queue state-machine tests
|
||||
* Atomic claim tests
|
||||
* Lease recovery tests
|
||||
* Idempotency tests
|
||||
* Retry tests
|
||||
* Cancellation tests
|
||||
* Tenant isolation tests
|
||||
* Restart recovery integration tests
|
||||
* Ollama adapter tests
|
||||
* External adapter tests
|
||||
* Frontend queued-state tests
|
||||
* End-to-end Strategy Snapshot tests
|
||||
* End-to-end CV-processing tests
|
||||
|
||||
Do not weaken existing tests.
|
||||
|
||||
## Final report
|
||||
|
||||
Report:
|
||||
|
||||
1. Verified production hardware
|
||||
2. Ollama version and configuration
|
||||
3. Models benchmarked
|
||||
4. Benchmark results
|
||||
5. Selected primary local model and why
|
||||
6. Selected context and tuning
|
||||
7. Installed model and digest
|
||||
8. Application provider order
|
||||
9. Queue architecture
|
||||
10. Privacy policy
|
||||
11. External fallback rules
|
||||
12. Production changes
|
||||
13. Database migrations
|
||||
14. Tests and results
|
||||
15. Production smoke-test results
|
||||
16. Resource usage before and after
|
||||
17. Rollback procedure
|
||||
18. Remaining limitations
|
||||
19. Tasks still requiring external AI
|
||||
20. Recommended future hardware upgrade, if evidence supports one
|
||||
|
||||
Do not claim the production rollout succeeded unless the deployed application, queue, Ollama model, restart recovery and local-first routing were genuinely verified.
|
||||
@@ -0,0 +1,922 @@
|
||||
Continue working on JobTracker using the completed audit under `docs/audits/`.
|
||||
|
||||
This is now an implementation task. Read all audit reports, evidence, repository instructions, architecture documentation, and the current git status before changing code.
|
||||
|
||||
Do not discard, overwrite, revert, or commit unrelated existing changes.
|
||||
|
||||
## Objective
|
||||
|
||||
Implement the following reliability, UX, subscription, email, Career Workspace, CV Builder, job-search, application-workspace, theme, and analysis improvements.
|
||||
|
||||
Work in small independently testable phases. Do not attempt one enormous rewrite.
|
||||
|
||||
If one item becomes blocked, document the blocker and continue with another safe work item. Ask for input only when a missing decision would materially alter the product. The Gmail/Correspondence decisions have already been made below.
|
||||
|
||||
Do not deploy to production unless explicitly instructed.
|
||||
|
||||
## Existing audit constraints
|
||||
|
||||
Treat the existing audit findings as authoritative inputs but revalidate affected code before changing it.
|
||||
|
||||
In particular, do not introduce changes that worsen or bypass:
|
||||
|
||||
* Tenant isolation
|
||||
* Microsoft identity safety
|
||||
* Host/origin validation
|
||||
* Email ownership verification
|
||||
* Session invalidation
|
||||
* Document-processing isolation
|
||||
* Account deletion and data export
|
||||
* AI privacy controls
|
||||
* Notification persistence
|
||||
* Provider authorization
|
||||
|
||||
If a requested change overlaps an unresolved High security finding, identify and implement the necessary security prerequisite in a dedicated work package or explicitly mark the feature as blocked. Do not casually combine identity migrations with a visual login redesign.
|
||||
|
||||
## Phase 1: Baseline and implementation plan
|
||||
|
||||
Before implementation:
|
||||
|
||||
1. Read every document under `docs/audits/`.
|
||||
2. Inspect the current git status.
|
||||
3. Read all applicable `AGENTS.md` files.
|
||||
4. Map the affected frontend, backend, Python, database and integration components.
|
||||
5. Run the existing baseline tests.
|
||||
6. Reproduce reported problems where safely possible.
|
||||
7. Create or update:
|
||||
|
||||
`docs/plans/post-audit-ux-reliability-program.md`
|
||||
|
||||
The plan must:
|
||||
|
||||
* Map each requested change to affected components.
|
||||
* Identify dependencies between work items.
|
||||
* Identify related audit findings.
|
||||
* Define acceptance criteria.
|
||||
* Define required tests.
|
||||
* Separate confirmed defects from redesign preferences.
|
||||
* Record anything that cannot be reproduced.
|
||||
* Define small implementation phases.
|
||||
|
||||
After creating the plan, continue implementing it. Do not stop merely to present the plan.
|
||||
|
||||
## Phase 2: Authentication-page redesign
|
||||
|
||||
Redesign the sign-in experience as a conventional single login form.
|
||||
|
||||
### Required layout
|
||||
|
||||
Use one unified sign-in card containing:
|
||||
|
||||
1. Username field
|
||||
2. Password field
|
||||
3. Primary sign-in button
|
||||
4. A visual separator containing `or`
|
||||
5. Continue with Google button
|
||||
6. Continue with Microsoft button
|
||||
7. Appropriate links for registration and password recovery
|
||||
|
||||
Remove separate Google and Microsoft tabs or panels.
|
||||
|
||||
Remove these texts and do not replace them with equivalent provider-status clutter:
|
||||
|
||||
* `Google account`
|
||||
* `Available to link`
|
||||
* `Continue with Google. New here? We'll create your account automatically.`
|
||||
|
||||
Also remove equivalent unnecessary Microsoft provider-status explanatory text.
|
||||
|
||||
The social buttons should look like normal alternative sign-in options rather than account-linking configuration panels.
|
||||
|
||||
### Requirements
|
||||
|
||||
* Preserve correct authentication behaviour.
|
||||
* Do not imply that accounts are linked merely by sharing an email address.
|
||||
* Do not weaken Microsoft issuer/tenant validation.
|
||||
* Do not introduce unsafe automatic identity linking.
|
||||
* Maintain accessible labels, focus order, keyboard support and error messages.
|
||||
* Clearly distinguish signing in from registering.
|
||||
* Test invalid credentials, provider failure, cancellation and direct return from an OAuth provider.
|
||||
* Ensure the design works in light and dark modes and on mobile widths.
|
||||
|
||||
## Phase 3: Theme-state reliability
|
||||
|
||||
Investigate why the application appears to switch into dark mode randomly.
|
||||
|
||||
Trace all theme sources, including:
|
||||
|
||||
* System preference
|
||||
* Local storage
|
||||
* User profile settings
|
||||
* React state
|
||||
* Initial page hydration
|
||||
* Cross-tab storage events
|
||||
* Login/logout
|
||||
* Route changes
|
||||
* Browser preference-change listeners
|
||||
* Server-rendered or initial HTML classes
|
||||
* Component-level theme overrides
|
||||
|
||||
Implement one deterministic precedence order:
|
||||
|
||||
1. Explicit saved user preference
|
||||
2. Explicit local preference for anonymous users
|
||||
3. System preference only when the selected setting is `System`
|
||||
4. Documented default when no preference exists
|
||||
|
||||
Requirements:
|
||||
|
||||
* Light mode must not change because the operating system changes if the user explicitly selected Light.
|
||||
* Dark mode must not change unexpectedly during navigation.
|
||||
* Avoid a flash of the wrong theme during startup.
|
||||
* Synchronise legitimate theme changes across tabs without generating loops.
|
||||
* Add tests covering explicit Light, explicit Dark, System, login, logout, refresh and navigation.
|
||||
|
||||
## Phase 4: Job-search expansion
|
||||
|
||||
Expand and redesign the job-search page to make listings easier to assess.
|
||||
|
||||
At minimum, display the source of every job.
|
||||
|
||||
### Source behaviour
|
||||
|
||||
Display:
|
||||
|
||||
* Source name
|
||||
* Recognisable source badge or icon where appropriate
|
||||
* Link to the original listing
|
||||
* Whether the source is imported, searched, scraped, manually entered or otherwise obtained
|
||||
* Retrieval/import date where available
|
||||
* Application deadline where available
|
||||
|
||||
Do not present an inferred source as verified. If the source is derived from the URL hostname, store or label it appropriately.
|
||||
|
||||
Add source filtering if supported by the available data.
|
||||
|
||||
Review the entire page from a user perspective and improve:
|
||||
|
||||
* Scanability
|
||||
* Search
|
||||
* Filters
|
||||
* Sorting
|
||||
* Location presentation
|
||||
* Remote/hybrid/on-site information
|
||||
* Deadline visibility
|
||||
* Loading states
|
||||
* Empty states
|
||||
* Errors
|
||||
* Duplicate jobs
|
||||
* Import-to-tracker action
|
||||
* Mobile layout
|
||||
|
||||
Preserve source attribution through import into the tracker.
|
||||
|
||||
## Phase 5: Job-analysis and keyword-quality correction
|
||||
|
||||
Investigate the complete pipeline that produces outputs such as:
|
||||
|
||||
`Keywords to mirror:`
|
||||
|
||||
* `med`
|
||||
* `til`
|
||||
* `for`
|
||||
* `som`
|
||||
* `erfaring`
|
||||
|
||||
These are low-information Norwegian function words or generic recruitment terms and should not be presented as useful keywords to mirror.
|
||||
|
||||
Trace:
|
||||
|
||||
* Job-description extraction
|
||||
* HTML/text cleanup
|
||||
* Language detection
|
||||
* Tokenisation
|
||||
* Normalisation
|
||||
* Stop-word filtering
|
||||
* Phrase extraction
|
||||
* Skill extraction
|
||||
* Frequency scoring
|
||||
* AI prompts
|
||||
* Deterministic post-processing
|
||||
* Frontend presentation
|
||||
* Storage and caching of analysis results
|
||||
|
||||
Do not fix this by hardcoding only the five examples above.
|
||||
|
||||
### Required behaviour
|
||||
|
||||
The keyword analysis should prioritise meaningful items such as:
|
||||
|
||||
* Named technologies
|
||||
* Tools
|
||||
* Programming languages
|
||||
* Frameworks
|
||||
* Platforms
|
||||
* Qualifications
|
||||
* Domain knowledge
|
||||
* Responsibilities
|
||||
* Important multi-word phrases
|
||||
* Role-specific terminology
|
||||
* Relevant soft skills only when genuinely prominent
|
||||
|
||||
It should suppress:
|
||||
|
||||
* Norwegian and English function words
|
||||
* Generic recruitment filler
|
||||
* Isolated prepositions and conjunctions
|
||||
* Boilerplate
|
||||
* Navigation text
|
||||
* Cookie text
|
||||
* Repeated source-page chrome
|
||||
* Extremely common terms with no useful tailoring value
|
||||
|
||||
Treat generic terms contextually. For example, `erfaring` alone is low-value, but a phrase such as `erfaring med ASP.NET Core` may contain valuable information.
|
||||
|
||||
Preserve meaningful punctuation and technology names such as:
|
||||
|
||||
* C#
|
||||
* .NET
|
||||
* ASP.NET Core
|
||||
* Node.js
|
||||
* CI/CD
|
||||
* C++
|
||||
* Azure DevOps
|
||||
|
||||
Prefer meaningful phrases over isolated tokens.
|
||||
|
||||
### Verification
|
||||
|
||||
Create representative fixtures for:
|
||||
|
||||
* Norwegian job advertisement
|
||||
* English job advertisement
|
||||
* Mixed Norwegian/English advertisement
|
||||
* Short advertisement
|
||||
* Noisy HTML advertisement
|
||||
* Technology-heavy advertisement
|
||||
* Advertisement with repeated generic recruitment language
|
||||
|
||||
Tests must demonstrate that low-value terms are excluded while meaningful phrases and technologies remain.
|
||||
|
||||
Review the label `Keywords to mirror`. If it is misleading, replace it with clearer user-facing language such as `Important terms from the job`, while preserving honest explanations of what the analysis represents.
|
||||
|
||||
Recalculate stale analysis results safely where appropriate. Do not silently change historical results without considering versioning or regeneration behaviour.
|
||||
|
||||
## Phase 6: Career Workspace redesign
|
||||
|
||||
Review the entire Career Workspace as a user trying to understand what to do next.
|
||||
|
||||
Remove this text unless usability testing demonstrates that a shorter explanation is genuinely needed:
|
||||
|
||||
`Your career profile holds your information. The CV Builder creates documents from it — job-specific CVs stay separate and never overwrite your profile.`
|
||||
|
||||
Do not replace it with another large explanatory paragraph.
|
||||
|
||||
Redesign the page around clear actions and progressive disclosure.
|
||||
|
||||
The workspace should make it obvious how to:
|
||||
|
||||
* Create or improve the Career Profile
|
||||
* Import a CV
|
||||
* Review extracted information
|
||||
* Resume an incomplete import
|
||||
* Open the CV Builder
|
||||
* Create a general CV
|
||||
* Create a job-specific CV
|
||||
* See recent documents
|
||||
* Understand profile completeness
|
||||
* Resolve missing information
|
||||
* View processing status and failures
|
||||
|
||||
Use concise contextual guidance near the relevant action instead of large introductory explanations.
|
||||
|
||||
Review:
|
||||
|
||||
* Information hierarchy
|
||||
* Empty state
|
||||
* First-run experience
|
||||
* Returning-user experience
|
||||
* Loading and processing state
|
||||
* Import-review state
|
||||
* Errors
|
||||
* Mobile layout
|
||||
* Keyboard navigation
|
||||
* Accessibility
|
||||
* Light and dark mode
|
||||
|
||||
Do not let imported CV data overwrite the Career Profile without the existing review and approval gate.
|
||||
|
||||
## Phase 7: CV upload 504 investigation
|
||||
|
||||
Reproduce and diagnose the 504 error when uploading and processing this authorised test document:
|
||||
|
||||
`F:\Documents\Work\CV and stuff\New CV\Connor Babbington - CV -English-.pdf`
|
||||
|
||||
The user has authorised this file for local testing.
|
||||
|
||||
### Data-handling restrictions
|
||||
|
||||
* Do not modify the original.
|
||||
* Do not commit the document.
|
||||
* Do not expose its contents in reports, logs or screenshots.
|
||||
* Do not upload it to unrelated external services.
|
||||
* Use a temporary working copy if required.
|
||||
* Remove temporary copies when testing finishes.
|
||||
|
||||
Trace the complete request:
|
||||
|
||||
1. Browser upload
|
||||
2. Frontend request
|
||||
3. Reverse proxy
|
||||
4. ASP.NET API
|
||||
5. File persistence
|
||||
6. Python/FastAPI processing
|
||||
7. Document parser
|
||||
8. AI normalisation if applicable
|
||||
9. Database persistence
|
||||
10. Review-result polling or response
|
||||
|
||||
Determine where the 504 originates.
|
||||
|
||||
Inspect:
|
||||
|
||||
* Proxy timeout
|
||||
* Backend timeout
|
||||
* Python timeout
|
||||
* Synchronous long-running request
|
||||
* Parser performance
|
||||
* Excessive page/image processing
|
||||
* Deadlock
|
||||
* Retry loop
|
||||
* Network resolution
|
||||
* Container health
|
||||
* File-size handling
|
||||
* AI-provider latency
|
||||
* Lost background work
|
||||
* Missing progress state
|
||||
|
||||
Do not solve the problem merely by increasing every timeout.
|
||||
|
||||
If processing can reasonably exceed an interactive HTTP request duration, redesign it as a durable background operation with:
|
||||
|
||||
* Accepted response
|
||||
* Stable processing ID
|
||||
* Persistent state
|
||||
* Progress or clear status
|
||||
* Polling or push updates
|
||||
* Explicit failure details
|
||||
* Bounded retries
|
||||
* Idempotency
|
||||
* Cancellation or safe abandonment
|
||||
* Cleanup
|
||||
* Recovery after restart
|
||||
|
||||
Coordinate this work with JT-006 document-parser hardening:
|
||||
|
||||
* Size limits
|
||||
* Page limits
|
||||
* Pixel limits
|
||||
* Memory limits
|
||||
* Processing timeout
|
||||
* Isolated parsing
|
||||
* Safe temporary files
|
||||
* Cleanup
|
||||
* Updated parser versions
|
||||
|
||||
Add regression tests using safe fixtures.
|
||||
|
||||
## Phase 8: CV Builder redesign
|
||||
|
||||
Analyse the interaction model of:
|
||||
|
||||
`https://app.flowcv.com/resume/content`
|
||||
|
||||
Use browser tooling to inspect the accessible application thoroughly.
|
||||
|
||||
If authentication is required, use an existing authorised browser session or request manual sign-in takeover. Do not bypass authentication. If access remains blocked, document the limitation and continue with the other work rather than pretending the analysis was complete.
|
||||
|
||||
Analyse interaction patterns including:
|
||||
|
||||
* Section list
|
||||
* Expandable/collapsible sections
|
||||
* Inline editing
|
||||
* Adding entries
|
||||
* Reordering sections
|
||||
* Reordering entries
|
||||
* Visibility controls
|
||||
* Duplicate/delete behaviour
|
||||
* Navigation
|
||||
* Autosave feedback
|
||||
* Unsaved changes
|
||||
* Validation
|
||||
* Preview relationship
|
||||
* Desktop layout
|
||||
* Mobile behaviour
|
||||
* Keyboard accessibility
|
||||
* Focus management
|
||||
* Empty states
|
||||
* Error handling
|
||||
|
||||
Do not copy FlowCV’s code, branding, assets, wording or exact visual design. Use it only as product-interaction research and create an original JobTracker design consistent with the existing design system.
|
||||
|
||||
### Required JobTracker behaviour
|
||||
|
||||
On `/career/builder/`, users must be able to:
|
||||
|
||||
* See all CV sections in a clear ordered list
|
||||
* Expand and collapse individual sections
|
||||
* Edit section content directly
|
||||
* Add entries
|
||||
* Delete entries with confirmation where appropriate
|
||||
* Reorder entries
|
||||
* Reorder supported sections
|
||||
* Hide or show optional sections
|
||||
* See validation near affected fields
|
||||
* Understand saved, saving, unsaved and failed states
|
||||
* Navigate away without silently losing changes
|
||||
* Preview the CV without abandoning the editing context
|
||||
|
||||
Evaluate whether a split editor/preview layout, drawer, tabs or responsive alternative works best for JobTracker. Base the decision on user workflow and available screen width.
|
||||
|
||||
Preserve:
|
||||
|
||||
* Existing CV data
|
||||
* Existing templates
|
||||
* Public CV rendering
|
||||
* PDF/DOCX generation
|
||||
* General and job-specific CV separation
|
||||
* Career Profile separation
|
||||
* Versioning
|
||||
* Import review behaviour
|
||||
|
||||
Add tests for editing, collapsing, adding, deleting, reordering, saving, failures and data persistence.
|
||||
|
||||
## Phase 9: Consolidated job-email experience
|
||||
|
||||
The product decisions are final:
|
||||
|
||||
1. Include job-related messages, including unlinked recruitment messages that may belong to an application.
|
||||
2. Use one consolidated email hub, with relevant correspondence also embedded within each application workspace.
|
||||
3. Allow users to draft, review and then explicitly send through the connected provider.
|
||||
|
||||
Redesign Gmail Review and Correspondence around these decisions.
|
||||
|
||||
### Information architecture
|
||||
|
||||
Replace the current overlapping pages with one coherent job-email hub.
|
||||
|
||||
The hub should support:
|
||||
|
||||
* Linked job correspondence
|
||||
* Likely recruitment messages not yet linked
|
||||
* Clear provider identity
|
||||
* Gmail and Outlook compatibility
|
||||
* Search
|
||||
* Filtering
|
||||
* Read/unread
|
||||
* Pinning
|
||||
* Read later
|
||||
* Archive
|
||||
* Spam/trash states where supported
|
||||
* Suggested job link
|
||||
* Manual job linking
|
||||
* Unlinking with confirmation
|
||||
* Thread detail
|
||||
* Attachments
|
||||
* Drafting
|
||||
* Follow-up state
|
||||
* Provider errors
|
||||
* Reauthorization
|
||||
|
||||
Correspondence for a specific job must also appear inside that job’s application workspace without becoming a separate inconsistent copy.
|
||||
|
||||
Use one underlying domain model and shared components where practical.
|
||||
|
||||
### Drafting and sending
|
||||
|
||||
* Drafts must remain editable.
|
||||
* AI may assist Pro users, but must never send autonomously.
|
||||
* The user must explicitly review and confirm sending.
|
||||
* Clearly show recipient, subject, thread and provider before sending.
|
||||
* Prevent duplicate sends.
|
||||
* Handle provider failure and uncertain send status safely.
|
||||
* Preserve an audit trail without logging sensitive contents unnecessarily.
|
||||
* Free users should still have the intended non-AI email functionality unless the existing product definition says otherwise.
|
||||
* Pro gating should apply specifically to AI assistance rather than disguising basic email access as AI.
|
||||
|
||||
### Recruitment-message detection
|
||||
|
||||
If the system identifies likely recruitment email:
|
||||
|
||||
* Show it as a suggestion, not a fact.
|
||||
* Explain the relevant signal where practical.
|
||||
* Allow dismissal.
|
||||
* Do not automatically link messages based solely on mutable sender names or weak keyword matches.
|
||||
* Keep provider data tenant-scoped.
|
||||
|
||||
### Routes
|
||||
|
||||
Review whether the old Gmail Review and Correspondence routes should:
|
||||
|
||||
* Redirect to the consolidated hub
|
||||
* Open an appropriate filtered view
|
||||
* Be removed after a compatibility period
|
||||
|
||||
Avoid leaving duplicate implementations.
|
||||
|
||||
Add tests for linking, unlinking, drafting, explicit sending, provider failure, tenant isolation and job-workspace embedding.
|
||||
|
||||
## Phase 10: Kanban dark-mode correction
|
||||
|
||||
Fix the Kanban board in dark mode.
|
||||
|
||||
The draggable destination columns or boxes must not remain white.
|
||||
|
||||
Review every Kanban state:
|
||||
|
||||
* Empty column
|
||||
* Column containing cards
|
||||
* Drag start
|
||||
* Drag over
|
||||
* Valid drop target
|
||||
* Invalid drop target
|
||||
* Selected card
|
||||
* Hover
|
||||
* Keyboard drag
|
||||
* Loading
|
||||
* Error
|
||||
|
||||
Use shared theme tokens rather than isolated hardcoded colours.
|
||||
|
||||
Maintain:
|
||||
|
||||
* Sufficient contrast
|
||||
* Visible drop targets
|
||||
* Clear status distinctions
|
||||
* Accessible focus
|
||||
* Light-mode quality
|
||||
* Mobile behaviour
|
||||
|
||||
Add visual or component regression coverage where feasible.
|
||||
|
||||
## Phase 11: Job applications table and embedded workspace
|
||||
|
||||
Redesign the job-applications table from the user’s perspective.
|
||||
|
||||
Goals:
|
||||
|
||||
* Make applications easier to scan.
|
||||
* Make important details visible without overwhelming the table.
|
||||
* Make opening an application obvious.
|
||||
* Allow the application workspace to open within the list context instead of forcing navigation to a completely separate page.
|
||||
|
||||
### Table review
|
||||
|
||||
Evaluate and improve:
|
||||
|
||||
* Primary job/company identity
|
||||
* Status
|
||||
* Location
|
||||
* Source
|
||||
* Application date
|
||||
* Deadline
|
||||
* Last activity
|
||||
* Next follow-up
|
||||
* Match information
|
||||
* Unread correspondence
|
||||
* Tags
|
||||
* Sorting
|
||||
* Filtering
|
||||
* Search
|
||||
* Column priority
|
||||
* Responsive behaviour
|
||||
* Empty/loading/error states
|
||||
* Row actions
|
||||
|
||||
Do not place every possible field into the table.
|
||||
|
||||
### Application workspace presentation
|
||||
|
||||
Implement a clean modal, drawer or responsive overlay for the application workspace.
|
||||
|
||||
The design must:
|
||||
|
||||
* Preserve list context and filters
|
||||
* Support a shareable/deep-linkable URL
|
||||
* Work with browser Back/Forward
|
||||
* Allow direct URLs to open the correct application
|
||||
* Avoid losing unsaved changes
|
||||
* Be accessible
|
||||
* Trap and restore focus correctly
|
||||
* Close predictably
|
||||
* Work as an appropriate full-screen presentation on mobile
|
||||
* Avoid nested modal chaos
|
||||
* Present sections with strong hierarchy
|
||||
|
||||
Review and redesign the existing application workspace because it currently appears visually messy.
|
||||
|
||||
It should coherently contain applicable information such as:
|
||||
|
||||
* Job overview
|
||||
* Status and timeline
|
||||
* Notes
|
||||
* Tasks and follow-ups
|
||||
* Documents
|
||||
* Match analysis
|
||||
* Strategy snapshot
|
||||
* Interviews
|
||||
* Contacts
|
||||
* Embedded correspondence
|
||||
* Activity history
|
||||
|
||||
Use tabs, sections or progressive disclosure based on task flow rather than fitting everything onto one screen.
|
||||
|
||||
Preserve a full-page fallback where needed for accessibility, direct linking or smaller environments, but use the embedded workspace as the primary desktop interaction.
|
||||
|
||||
## Phase 12: Homepage and subscription model
|
||||
|
||||
Update the homepage and product messaging to represent exactly two plans:
|
||||
|
||||
### Free
|
||||
|
||||
* No AI features
|
||||
* Core non-AI job-tracking functionality
|
||||
|
||||
### Pro
|
||||
|
||||
* AI-assisted functionality
|
||||
* All explicitly defined Pro capabilities
|
||||
|
||||
There are no additional membership tiers unless confirmed by existing product requirements.
|
||||
|
||||
Remove outdated plan claims and contradictory pricing/membership language throughout:
|
||||
|
||||
* Homepage
|
||||
* Pricing sections
|
||||
* Registration
|
||||
* Settings
|
||||
* Upgrade prompts
|
||||
* Feature descriptions
|
||||
* Navigation
|
||||
* Help text
|
||||
* Metadata
|
||||
* Tests
|
||||
* Configuration
|
||||
|
||||
Create one central capability/entitlement definition instead of scattering plan checks across components.
|
||||
|
||||
Do not invent prices, billing intervals, trials or limits that have not been defined.
|
||||
|
||||
## Phase 13: Pro feature enforcement and promotion
|
||||
|
||||
Inventory every AI-powered or otherwise Pro-only feature.
|
||||
|
||||
For each feature, document:
|
||||
|
||||
* User-facing entry point
|
||||
* Frontend component
|
||||
* API endpoint
|
||||
* Background worker
|
||||
* Entitlement check
|
||||
* Usage accounting
|
||||
* Failure behaviour
|
||||
* Upgrade experience
|
||||
|
||||
Enforce Pro access server-side. Hiding a button is not sufficient.
|
||||
|
||||
The frontend should also present appropriate locked states.
|
||||
|
||||
### Upgrade promotion
|
||||
|
||||
For Free users:
|
||||
|
||||
* Show a clear locked state where a Pro feature would otherwise be useful.
|
||||
* Explain the practical benefit.
|
||||
* Provide an upgrade action.
|
||||
* Do not imply that work was generated when it was not.
|
||||
* Do not repeatedly interrupt users.
|
||||
* Make promotional notices dismissible where appropriate.
|
||||
* Avoid dark patterns, artificial urgency and excessive notification spam.
|
||||
* Preserve access to the user’s existing non-AI data.
|
||||
|
||||
Examples may include contextual messages such as:
|
||||
|
||||
* Generate a tailored strategy with Pro
|
||||
* Get AI-assisted CV suggestions with Pro
|
||||
* Draft a follow-up with Pro
|
||||
|
||||
Use concise benefit-focused text rather than generic advertising.
|
||||
|
||||
### Backend requirements
|
||||
|
||||
* Centralised entitlement policy
|
||||
* Consistent API responses for locked features
|
||||
* No background execution for unauthorised users
|
||||
* No bypass through direct requests
|
||||
* Correct admin/test handling
|
||||
* Tenant isolation
|
||||
* Appropriate usage tracking
|
||||
* Tests covering Free, Pro, expired/downgraded and administrative scenarios
|
||||
|
||||
Do not implement billing-provider functionality unless it already exists and is within scope.
|
||||
|
||||
## Phase 14: Timeouts and Strategy Snapshot
|
||||
|
||||
Reproduce the reported timeouts, particularly:
|
||||
|
||||
`Generate strategy snapshot`
|
||||
|
||||
Trace the complete path:
|
||||
|
||||
* Button action
|
||||
* Frontend request
|
||||
* API endpoint
|
||||
* Authorization
|
||||
* Pro entitlement
|
||||
* Database access
|
||||
* AI/background service
|
||||
* Provider request
|
||||
* Proxy
|
||||
* Persistence
|
||||
* UI refresh
|
||||
|
||||
Determine whether failures are caused by:
|
||||
|
||||
* Ambiguous routes
|
||||
* SQLite incompatibility
|
||||
* Inert hosted services
|
||||
* Proxy timeout
|
||||
* AI-provider timeout
|
||||
* Synchronous long-running work
|
||||
* Retry storms
|
||||
* Missing cancellation
|
||||
* Deadlock
|
||||
* Unbounded input
|
||||
* Lost background work
|
||||
* Frontend timeout
|
||||
* Incorrect error translation
|
||||
|
||||
Do not mask the root cause with a larger timeout.
|
||||
|
||||
Long-running generation should use a durable operation with:
|
||||
|
||||
* Persistent job record
|
||||
* Stable operation ID
|
||||
* Queued/running/succeeded/failed/cancelled state
|
||||
* Bounded retries
|
||||
* Timeout
|
||||
* Idempotency
|
||||
* Progress or honest status
|
||||
* Recovery after process restart
|
||||
* Clear user-facing errors
|
||||
* Safe retry
|
||||
* No duplicate billing or duplicate output
|
||||
|
||||
AI requests must respect Pro entitlement and privacy controls on the server.
|
||||
|
||||
Test success, provider failure, timeout, cancellation, retry, duplicate clicks, refresh and application restart.
|
||||
|
||||
## Phase 15: Complete action verification
|
||||
|
||||
Create:
|
||||
|
||||
`docs/verification/application-action-matrix.md`
|
||||
|
||||
Inventory every meaningful user action in the application, including:
|
||||
|
||||
* Buttons
|
||||
* Links
|
||||
* Forms
|
||||
* Menus
|
||||
* Context actions
|
||||
* Drag-and-drop operations
|
||||
* Uploads
|
||||
* Downloads
|
||||
* Exports
|
||||
* Authentication actions
|
||||
* Settings
|
||||
* Job actions
|
||||
* Career Profile actions
|
||||
* CV actions
|
||||
* Email actions
|
||||
* AI actions
|
||||
* Administrative actions
|
||||
* Destructive actions
|
||||
* Mobile-specific actions
|
||||
|
||||
For each action record:
|
||||
|
||||
* Page/route
|
||||
* User role
|
||||
* Free or Pro
|
||||
* Control
|
||||
* Expected result
|
||||
* API/background path
|
||||
* Loading behaviour
|
||||
* Success feedback
|
||||
* Failure feedback
|
||||
* Authorization
|
||||
* Tenant isolation
|
||||
* Test coverage
|
||||
* Manual verification result
|
||||
* Automated verification result
|
||||
* Finding or fix reference
|
||||
|
||||
Exercise every safe action in a running application.
|
||||
|
||||
Use synthetic accounts and data. Do not send real email, invoke paid providers, alter production data or perform irreversible external actions.
|
||||
|
||||
Classify actions as:
|
||||
|
||||
* Verified working
|
||||
* Fixed and verified
|
||||
* Failing
|
||||
* Blocked by external dependency
|
||||
* Mock-tested
|
||||
* Code-inspected only
|
||||
* Not applicable
|
||||
|
||||
Pay particular attention to:
|
||||
|
||||
* 500 responses
|
||||
* 504 responses
|
||||
* Silent failures
|
||||
* Buttons that do nothing
|
||||
* Duplicate submissions
|
||||
* Indefinite spinners
|
||||
* Lost updates
|
||||
* Stale data
|
||||
* Incorrect success messages
|
||||
* Operations that succeed server-side but appear failed
|
||||
* Operations that fail server-side but appear successful
|
||||
|
||||
Continue fixing in-scope defects uncovered by this matrix. Add regression tests for each confirmed defect.
|
||||
|
||||
If an unrelated security-critical problem is found, document it immediately and handle it as a dedicated work package.
|
||||
|
||||
## Implementation quality requirements
|
||||
|
||||
For every work package:
|
||||
|
||||
1. Reproduce or establish the current behaviour.
|
||||
2. Identify the root cause.
|
||||
3. Define acceptance criteria.
|
||||
4. Implement the smallest cohesive solution.
|
||||
5. Add or update tests.
|
||||
6. Run focused verification.
|
||||
7. Run the relevant wider test suites.
|
||||
8. Review accessibility.
|
||||
9. Review light and dark modes.
|
||||
10. Update documentation.
|
||||
11. Record remaining limitations.
|
||||
|
||||
Do not run repository-wide automatic formatting merely to address the existing 1,301 formatting diagnostics. Format only touched files unless a dedicated formatting phase is approved.
|
||||
|
||||
Do not weaken tests to make them pass.
|
||||
|
||||
Do not replace real assertions with snapshots that merely capture incorrect behaviour.
|
||||
|
||||
## Browser and viewport verification
|
||||
|
||||
Test affected interfaces in Chromium at approximately:
|
||||
|
||||
* 375px
|
||||
* 768px
|
||||
* 1440px
|
||||
|
||||
Verify:
|
||||
|
||||
* Light mode
|
||||
* Dark mode
|
||||
* Keyboard navigation
|
||||
* Focus management
|
||||
* Loading
|
||||
* Empty states
|
||||
* Errors
|
||||
* Long text
|
||||
* Norwegian characters
|
||||
* Back/Forward navigation
|
||||
* Refresh
|
||||
* Multiple tabs where relevant
|
||||
* Slow or interrupted requests where feasible
|
||||
|
||||
Capture safe screenshots for material redesigns. Do not include private CV or email contents.
|
||||
|
||||
## Completion report
|
||||
|
||||
When all possible work is complete, provide:
|
||||
|
||||
1. Implemented work packages
|
||||
2. Root causes fixed
|
||||
3. Files changed
|
||||
4. Database/configuration changes
|
||||
5. Tests added
|
||||
6. Commands run and results
|
||||
7. Browser journeys verified
|
||||
8. Screenshots/evidence
|
||||
9. Remaining failures
|
||||
10. Blocked external-provider checks
|
||||
11. Outstanding audit findings
|
||||
12. Recommended next work package
|
||||
|
||||
Do not claim a workflow works unless it was genuinely browser-tested, mock-tested or otherwise clearly identified by verification type.
|
||||
Reference in New Issue
Block a user