The project starts from scratch and is implemented strictly in the stages defined in AGENTS.md, but Stage 1 is split into two internal sub-stages: foundation first, then core HTML logic. The architecture must stay simple, readable, and free from premature complexity. Shared domain logic must be reused across both HTML and API layers.
- Initialize the Django project
knowledge_baseand the apps:accounts,notes,tags,comments,votes,favorites,api,core. - Build the base structure:
corefor shared utilities, mixins, selectors/queryset helpers, constants, and slug logic;- shared templates with
base.html, navigation, messages, and base layout; - a single
settings.pywithout unnecessary decomposition.
- Add HTML authentication:
login/logout/signup. - Implement models and migrations:
Profilewith automatic creation for each user;Tag(name, slug);Note(title, slug, content, author, is_public, created_at, updated_at, view_count, tags);Comment(note, author, text, created_at, updated_at, is_deleted);Vote(note, user, value, created_at);Favorite(user, note, created_at).
- Fix the model rules:
Note.slugandTag.slugare unique and auto-generated if empty;Tag.nameis case-insensitively unique;Tag.namemust be normalized at the model/validation layer and protected by a database-level constraint;Vote.valueis aSmallIntegerFieldwith choices[(1, "up"), (-1, "down")];Vote(note, user)andFavorite(user, note)useUniqueConstraint.
- Implement Django admin for all models with useful search, filters, and related-field optimization.
- Implement the HTML routes:
//notes//notes/<slug>//notes/create//notes/<slug>/edit//tags/<slug>//profile/<username>/
- Access rules:
- public notes are visible to everyone;
- private notes are visible only to the author;
- only the author can create, edit, and delete notes.
- Implement:
- notes list page;
- note detail page;
- note create and edit pages;
- tag page;
- profile page with user notes.
- Search:
- search by
title__icontains,content__icontains, andtags__name__icontains; - use
distinct()when tag joins would otherwise produce duplicates.
- search by
- Pagination:
- add basic pagination to note lists;
- apply it to profile and tag pages when needed.
view_count:- increment with
F()expression on note detail page open; - at the early stage, count simple page opens only, without unique tracking by user, IP, or session.
- increment with
comments_countandvote_score:- compute via queryset helpers / annotations;
- do not use properties that trigger extra queries in list or detail views.
- Build list and detail views on shared selectors/queryset helpers from the start to avoid duplicated visibility and annotation logic.
- Add comments:
- only authenticated users can comment;
- only the comment author or staff can edit and delete;
- deletion is soft delete only via
is_deleted=True; - deleted comments are shown as deleted without the original text.
- Add voting:
- one user can have only one vote per note;
- if the user votes again with the same value, nothing changes;
- if the user votes with the opposite value, the existing vote is updated.
- Add favorites:
- add note to favorites;
- remove note from favorites;
- prevent duplicates;
- enable
/favorites/only at this stage as a full page.
- Extend selectors/queryset helpers for comments, votes, favorites, and profile views to avoid N+1 queries and rule duplication.
- Add DRF and JWT only after Stage 1 and Stage 2 are finished.
- Implement the API exactly as defined in
AGENTS.md:/api/auth/token//api/auth/token/refresh//api/notes//api/notes/<slug>//api/notes/<slug>/comments//api/notes/<slug>/vote//api/notes/<slug>/favorite//api/favorites//api/tags//api/tags/<slug>/notes/
- HTML and API must use the same selectors/queryset helpers for:
- note visibility rules;
comments_countandvote_score;select_related/prefetch_relatedoptimization;- search and filtering where applicable.
- API business rules must fully match the HTML business rules:
- note privacy;
- author permissions;
- soft delete comments;
- vote update logic;
- add/remove favorite behavior.
- Add caching only in clearly safe places: public lists and public detail pages.
- Add Celery only for actually useful background tasks, without artificial complexity.
- Set up CI:
- tests;
- migration checks;
- linter/formatter.
- Finalize README and overall project polish.
- Early HTML interface:
GET /GET /notes/GET|POST /notes/create/GET /notes/<slug>/GET|POST /notes/<slug>/edit/GET /tags/<slug>/GET /profile/<username>/GET|POST /accounts/signup/GET|POST /accounts/login/POST /accounts/logout/
/favorites/is enabled only in Stage 2.- API is enabled only in Stage 3 and must follow the URLs from
AGENTS.md. - Model-level contracts:
Note.slugandTag.slugare unique and auto-generated;Tag.nameis case-insensitively unique;Vote.valueaccepts only1and-1via choices;Commentuses soft delete;Vote(note, user)andFavorite(user, note)are unique.
- After Stage 1:
- note creation;
- slug generation and uniqueness;
- case-insensitive
Tag.nameuniqueness; - public/private note visibility;
- preventing other users from editing чужие notes;
- search by
title__icontains,content__icontains, andtags__name__icontains; - no duplicates in tag-based search;
- pagination for note lists;
- correct
view_countincrement viaF().
- After Stage 2:
- only authenticated users can comment;
- soft delete for comments;
- comment edit/delete permissions;
- vote creation;
- repeated same-value vote does not change the record;
- switching
+1to-1and back updates the existing vote; - invalid vote values outside
1/-1are not allowed; - add/remove favorite;
/favorites/is available only to the owner;comments_countandvote_scorework without extra queries.
- After Stage 3:
- JWT auth and refresh;
- note read/update permissions;
- note privacy in API;
- comments/vote/favorite endpoints;
- tag endpoints;
- API reuses the same selectors/queryset helpers as HTML.
- After Stage 4:
- cache smoke test;
- background task smoke test;
- CI passes completely.
- The project starts from an empty directory except for
AGENTS.md. - The environment uses
Python 3.13.5,Django 5.1.5, andSQLiteat the start. - Code should be written so that moving to PostgreSQL later does not require redesigning the domain logic.
- Important comments in non-trivial places should be written in Russian.
- Do not add nested comments, markdown editor, AI features, Elasticsearch, team roles, or complex async features in the early stages.