# Candidate architecture `app/` is the behavior-preserving modular source tree accepted by the user on 2026-08-01. The original `webapp/` runtime remains the deployment rollback baseline until an explicitly approved switch. `next/` is a rejected, frozen implementation and is not a source for this directory. The application deliberately remains a modular monolith: one Python process, one SQLite WAL database, and a build-free HTML/CSS/JavaScript client. The migration changed source ownership and imports, not the technology stack or observable product behavior. ## Runtime path ```text browser -> frontend/shared/api.js -> backend HTTP transport and feature HTTP mixins -> feature services -> repositories / DataGateway / LLMGateway -> SQLite / market providers / model providers background scheduler -> backend/jobs -> the same feature services and repositories ``` ## Source ownership - `server.py` is the stable command/import facade. Runtime composition lives in `backend/application.py` and `backend/bootstrap/`. - `backend/http/` owns common authentication, request IDs, responses, static delivery, and error normalization. Feature-specific transport handlers live beside their feature. Exact POST endpoints that only delegate to one of those handlers use the explicit maps in `backend/application.py`; endpoints with path parameters, body handling, or special error semantics remain visible control flow in `RequestHandler`. - `backend/features//` owns the mechanically moved service, repository, HTTP, agent, or deterministic calculation code for that product area. - `backend/data/` owns provider construction, source policy, provenance, units, freshness, coverage, and display-versus-calculation eligibility. - `backend/database/` owns connection management, ordered migrations, and narrow repository adapters. Root `database.py` remains the legacy schema/composition anchor and combines the feature repository mixins; do not add feature queries to it. - `backend/jobs/` owns job definitions, locks, retries, idempotency, and persisted run state. - `backend/llm/` owns model selection, membership/quota checks, fallback, provider transport, streaming rules, and call audit. Feature agents only prepare messages and interpret feature-specific results. - `frontend/shared/` is the only browser API/state/Shell/component boundary. - `frontend/pages/` owns page-local behavior. The original runtime was split mechanically; source markers and preservation tests prove that the pieces reassemble to the audited original, apart from explicitly registered trial retirements. - `frontend/styles/`, `frontend/shared/tokens.css`, and the Wentian page stylesheet preserve the approved cascade and light/dark/mobile behavior. - `config/` is the versioned registry for pages, features, APIs, datasets, quality rules, jobs, and the generated candidate architecture inventory. Root modules such as `screener.py`, `tushare_client.py`, and `mentor_agent.py` are compatibility aliases to canonical modules. They contain no second implementation and remain only because the original public import surface is part of the preservation contract. ## Non-negotiable maintenance rules 1. Preserve account ownership in every user-private query and test it with two accounts. 2. Browser requests go through `frontend/shared/api.js`; provider calls go through the data boundary; model calls go through `backend/llm/`. 3. Calculation datasets fail closed when required source, date, unit, freshness, or coverage evidence is missing. Display fallbacks do not silently enter calculations. 4. Do not implement logic in both a root compatibility module and a canonical module. 5. Do not remove compatibility or uncertain code without reference scanning, old/new differential evidence, browser checks, and manual acceptance. 6. Run `python tools/verify_baseline.py` for every change and add `--e2e` when runtime or frontend behavior can be affected. The authoritative migration constraints and handoff procedure are in `../docs/migration/原版保真迁移总纲.md` and `../docs/migration/人工维护与本地切换指南.md`.