docs(codebase): add codebase map — stack, architecture, structure, schema, conventions, testing, integrations, concerns
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
140
.paul/codebase/architecture.md
Normal file
140
.paul/codebase/architecture.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Architecture
|
||||
|
||||
**Analysis Date:** 2026-04-27
|
||||
|
||||
## Pattern Overview
|
||||
|
||||
**Overall:** Custom PHP MVC Monolith (dual frontend — public + admin)
|
||||
|
||||
**Key Characteristics:**
|
||||
- Single shared `core/` layer powering both public and admin frontends
|
||||
- Front Controller routing via Apache rewrite → `index.php` → Router → Controller
|
||||
- All templating via Smarty (no JSON API, no SPA)
|
||||
- Session-based admin auth; anonymous public form with reCAPTCHA
|
||||
|
||||
## Layers
|
||||
|
||||
**Router / Front Controller:**
|
||||
- Purpose: Parse URL, select controller and action
|
||||
- Contains: `Router.class.php`, `index.php` entry points
|
||||
- Location: `_rejestracja/index.php`, `_rejestracja/Admin/index.php`
|
||||
- Depends on: Core class loader
|
||||
- Used by: Nothing (entry point)
|
||||
|
||||
**Controller Layer:**
|
||||
- Purpose: Handle request lifecycle — auth, business logic dispatch, template assignment
|
||||
- Contains: `*Controller.php` files; each has `preDispatch`, `{Name}Action`, `postDispatch`
|
||||
- Location: `_rejestracja/controller/` (public), `_rejestracja/Admin/controller/`
|
||||
- Depends on: DAL layer, Smarty, SessionProxy, Request
|
||||
- Used by: Router
|
||||
|
||||
**DAL Layer (Data Access):**
|
||||
- Purpose: Typed database access; maps rows to model objects
|
||||
- Contains: `Mf{Entity}DAL.class.php` files, `DefaultDAL.class.php` base
|
||||
- Location: `_rejestracja/core/model/`
|
||||
- Depends on: MySQL connection, `DalData` query config objects, `DataObject` base model
|
||||
- Used by: Controllers
|
||||
|
||||
**Model Layer:**
|
||||
- Purpose: Typed domain objects with getters/setters
|
||||
- Contains: `Mf{Entity}.class.php` with `$fields` array mapping DB columns to properties
|
||||
- Location: `_rejestracja/core/model/`
|
||||
- Depends on: `DataObject.class.php` base
|
||||
- Used by: DAL (hydration), Controllers, Templates (via Smarty assigns)
|
||||
|
||||
**Template Layer:**
|
||||
- Purpose: HTML rendering via Smarty
|
||||
- Contains: `.tpl` files, Smarty plugins (`{translate}`, `{formField}`, `{url}`, `{dropDownContainer}`)
|
||||
- Location: `_rejestracja/template/`, `_rejestracja/Admin/template/`
|
||||
- Depends on: Variables assigned in controller (`$this->smarty->assign(...)`)
|
||||
- Used by: Nothing (output layer)
|
||||
|
||||
## Data Flow
|
||||
|
||||
**Public Registration Request:**
|
||||
|
||||
1. Browser `POST /_rejestracja/index` → Apache rewrite → `_rejestracja/index.php`
|
||||
2. `Router` parses URL → selects `IndexController`
|
||||
3. `IndexController::preDispatch()` sets up shared context (Smarty, layout)
|
||||
4. `IndexController::IndexAction()` runs:
|
||||
- Validates reCAPTCHA
|
||||
- Reads POST via `Request::GetPost()`
|
||||
- Hydrates `MfParticipant` model
|
||||
- Calls `MfParticipantDAL::Save($obj)` → INSERT/UPDATE
|
||||
- Sends confirmation email via PHPMailer
|
||||
- `$this->smarty->assign(...)` + Smarty renders confirmation template
|
||||
5. HTML response returned to browser
|
||||
|
||||
**Admin Registration List Request:**
|
||||
|
||||
1. Browser `GET /_rejestracja/Admin/Calc/Reg` → `Admin/index.php` → Router
|
||||
2. `CalcController::preDispatch()` — calls `RunShared('Auth', $param)` (session check)
|
||||
3. `CalcController::RegAction()`:
|
||||
- `MfParticipantDAL::GetResult($dalData)` with sort DESC
|
||||
- `$this->smarty->assign('arrayObj', $arrayObjReg)`
|
||||
4. Smarty renders `Admin/template/partial/Calc/Reg.tpl`
|
||||
|
||||
**State Management:**
|
||||
- PHP sessions via `SessionProxy` for admin auth and transient UI state
|
||||
- No in-memory cache; every request hits MySQL
|
||||
|
||||
## Key Abstractions
|
||||
|
||||
**DataObject / Model:**
|
||||
- Purpose: Typed domain objects with `$fields` array auto-mapping DB↔PHP
|
||||
- Examples: `MfParticipant`, `MfParameters`, `MfDictionary`
|
||||
- Pattern: Active-record-lite; `$fields = ['db_col' => 'PropName']`, auto-generates getters/setters via `__get`/`__set` or explicit methods
|
||||
|
||||
**DefaultDAL / DalData:**
|
||||
- Purpose: Generic CRUD over MySQL; `DalData` is a query config object (conditions, sort, limit)
|
||||
- Examples: `MfParticipantDAL`, `MfParametersDAL`, `MfDictionaryDAL`
|
||||
- Pattern: `GetDalDataObj()` → configure → `GetResult()` / `GetById()` / `Save()` / `Delete()`
|
||||
|
||||
**Smarty Plugin Suite:**
|
||||
- Purpose: Template-level abstractions for common patterns
|
||||
- Key plugins: `{translate word='key'}` (dictionary lookup), `{formField name="" type=""}` (form inputs — text/hidden only), `{url label=X}` (router-aware URL generation), `{dropDownContainer}` (collapsible admin sections)
|
||||
- Pattern: Custom Smarty plugins registered in `_rejestracja/core/`
|
||||
|
||||
## Entry Points
|
||||
|
||||
**Public Frontend:**
|
||||
- Location: `_rejestracja/index.php`
|
||||
- Triggers: HTTP request to `/_rejestracja/`
|
||||
- Responsibilities: Bootstrap core, invoke Router → Controller
|
||||
|
||||
**Admin Frontend:**
|
||||
- Location: `_rejestracja/Admin/index.php`
|
||||
- Triggers: HTTP request to `/_rejestracja/Admin/`
|
||||
- Responsibilities: Same bootstrap + admin-specific auth via `RunShared('Auth')`
|
||||
|
||||
## Error Handling
|
||||
|
||||
**Strategy:** Mostly unhandled — exceptions catch in isolated blocks, errors logged to PHP error_log
|
||||
|
||||
**Patterns:**
|
||||
- `try/catch` in `RegDeleteAction` (DAL delete errors logged but swallowed)
|
||||
- `Validator` class collects field errors and returns them to template via `$out` array
|
||||
- No global exception handler observed
|
||||
|
||||
## Cross-Cutting Concerns
|
||||
|
||||
**Logging:**
|
||||
- PHP `error_log` only; `Utils::ArrayDisplay()` for dev debug (should be removed pre-deploy)
|
||||
|
||||
**Validation:**
|
||||
- `Validator` class at controller level for required-field checks
|
||||
- reCAPTCHA for bot protection on public form
|
||||
- No input sanitization layer beyond Smarty auto-escaping in templates
|
||||
|
||||
**Authentication:**
|
||||
- Admin: `RunShared('Auth', $param)` in every admin controller `preDispatch`
|
||||
- Public: None (anonymous registration form)
|
||||
|
||||
**Internationalization:**
|
||||
- `{translate word='key'}` Smarty plugin reads from `mf_dictionary` table
|
||||
- All visible strings for the registration form are dictionary-backed
|
||||
|
||||
---
|
||||
|
||||
*Architecture analysis: 2026-04-27*
|
||||
*Update when major patterns change*
|
||||
Reference in New Issue
Block a user