|
<div class="docs-content" data-render>
|
|
# Architecture overview
|
|
|
|
The design reference for the platform: the stack, the project structure, the central mental model every feature follows, and the principles that govern the code. The subpages drill into the backend, the frontend, styling, the conventions, and the development workflow.
|
|
|
|
> Audience: administrators and maintainers. These pages are hidden from members and guests, in the sidebar, the search index, and the documentation export.
|
|
|
|
## What DevPlace is
|
|
|
|
DevPlace is a server-rendered social network for developers. The backend renders HTML, and the same handlers serve JSON, drive the Devii assistant, and back the API documentation. There is no single-page-application layer and no client-side router: pages are HTML, enhanced in place by vanilla JavaScript.
|
|
|
|
## The stack
|
|
|
|
| Layer | Choice | Notes |
|
|
|-------|--------|-------|
|
|
| Web framework | FastAPI | Async route handlers, Pydantic validation, automatic OpenAPI. |
|
|
| Templates | Jinja2 | One shared `templates` instance with registered globals. |
|
|
| Database | SQLite via `dataset` | Synchronous by design, tuned with WAL. Schema auto-syncs. |
|
|
| Frontend JS | Vanilla ES6 modules | One class per file. No framework, no NPM, no bundler. |
|
|
| UI widgets | Custom web components | `dp-` prefix, light DOM, self-registering. |
|
|
| Styling | Vanilla CSS | Design tokens via custom properties. No preprocessor. |
|
|
| Auth | Session cookies + API keys | No JWT. |
|
|
|
|
The recurring theme is deliberate minimalism: no JavaScript framework, no NPM, no build step, no client-side rendering framework, no JWT, and a local SQLite file instead of a database server. Every dependency earns its place.
|
|
|
|
## Project structure
|
|
|
|
```
|
|
devplacepy/
|
|
main.py app, middleware, router registration, lifecycle
|
|
config.py paths, env vars, constants
|
|
database.py SQLite/dataset, init_db, batch helpers, caching
|
|
models.py Pydantic Form input models
|
|
schemas.py Pydantic *Out response projections
|
|
responses.py respond() / action_result() / wants_json()
|
|
utils.py auth guards, slugs, dates, gamification
|
|
templating.py the shared templates instance + globals
|
|
seo.py JSON-LD schema builders, base_seo_context
|
|
content.py shared content lifecycle (create/edit/delete)
|
|
routers/ URL-mirrored tree: flat file per single-resource domain, package per multi-sub-resource domain
|
|
services/ BaseService, ServiceManager, news/bots/gateway/devii
|
|
templates/ Jinja2 templates, base.html, partials, docs/
|
|
static/js/ ES6 modules, components/, devii/
|
|
static/css/ variables.css + base + per-page stylesheets
|
|
```
|
|
|
|
## The central mental model: one source, four faces
|
|
|
|
Every feature in DevPlace is **one data source fanning out into several consumers**. A single route handler is, at the same time:
|
|
|
|
1. **HTML** - `respond(request, template, ctx)` renders a Jinja template for browsers.
|
|
2. **JSON** - the same `respond(..., model=XOut)` returns JSON when the client asks. The `*Out` schema in `schemas.py` is the gate: a context key not declared on `*Out` is dropped from the JSON, even though the template still sees it.
|
|
3. **Devii tool** - an `Action` in the Devii catalog lets the assistant call the same capability.
|
|
4. **API docs** - an `endpoint()` entry documents it for developers.
|
|
|
|
The cardinal failure mode is changing one face and forgetting a connected one: adding a route but no JSON schema, a JSON endpoint but no Devii tool, or a feature but never documenting it. The [Development workflow](/docs/architecture-workflow.html) checklist is ordered by data flow so none of the four is dropped.
|
|
|
|
## Guiding principles
|
|
|
|
- **Readable over clever.** Beautiful, explicit code beats dense or implicit code.
|
|
- **Simple over complex.** Flat structures, one obvious way to do a thing, no special cases that break established patterns.
|
|
- **Never silence errors.** Failures surface; they are suppressed only when that is the explicit intent.
|
|
- **Self-documenting.** No comments and no docstrings in source; names carry the meaning.
|
|
- **Consistency is a feature.** The same pattern is reused across domains (polymorphic comments and votes, slug+UUID lookup, the `respond()` duality) so that learning one area teaches the others.
|
|
|
|
## The subpages
|
|
|
|
- [Backend and request pipeline](/docs/architecture-backend.html) - middleware, routing, database, caching, services.
|
|
- [Frontend and components](/docs/architecture-frontend.html) - vanilla JS, the Application root, web components, content rendering.
|
|
- [Styling and templates](/docs/architecture-styling.html) - vanilla CSS, design tokens, base templates, partials.
|
|
- [Conventions and rules](/docs/architecture-conventions.html) - the rule book: naming, dates, slugs, ownership, validation, SEO.
|
|
- [Development workflow](/docs/architecture-workflow.html) - the feature workflow, the documentation trio, and validation.
|
|
</div>
|