74 lines
6.7 KiB
Markdown
74 lines
6.7 KiB
Markdown
# Writer Module (Backend) — Code-Sourced Overview (Dec 2025)
|
|
|
|
Scope: `backend/igny8_core/modules/writer` (ViewSets/serializers/urls) backed by models in `backend/igny8_core/business/content`.
|
|
|
|
## Endpoints (from `modules/writer/urls.py`)
|
|
- `/api/v1/writer/tasks/` — CRUD + bulk delete/update, auto content generation.
|
|
- `/api/v1/writer/images/` — CRUD + serve file, auto generate images, bulk status update (by content or ids), grouped content images.
|
|
- `/api/v1/writer/content/` — CRUD + publish/unpublish to WordPress, check WordPress status, AI prompt generation, validation, metadata mapping, taxonomy/tag management.
|
|
- `/api/v1/writer/taxonomies/` — CRUD for content taxonomies (categories/tags). Attributes endpoint disabled (serializer removed).
|
|
|
|
## Models (business/content/models.py)
|
|
- **Tasks** (`SiteSectorBaseModel`, soft-delete): title, description, FK `cluster` (required, same sector), optional `idea`, `content_type` (post/page/product/taxonomy), `content_structure` (article/guide/landing_page/etc.), optional `taxonomy_term`, comma keywords, word_count, status (`queued|completed`). Indexes on title/status/cluster/type/structure/site+sector.
|
|
- **Content** (`SiteSectorBaseModel`, soft-delete): title, HTML, word_count, SEO fields, FK `cluster`, `content_type/structure`, M2M `taxonomy_terms` (through `ContentTaxonomyRelation`), external publishing fields (`external_id/url/type/metadata/sync_status`), source (`igny8|wordpress`), status (`draft|review|published`). Indexes on title/cluster/type/structure/source/status/external_id/site+sector.
|
|
- **ContentTaxonomy** (`SiteSectorBaseModel`): name, slug, `taxonomy_type (category|tag)`, external_taxonomy/id, sync_status, description, count, metadata. Unique per site+slug+type and site+external_id+external_taxonomy.
|
|
- **Images** (`SiteSectorBaseModel`, soft-delete): FK `content` (preferred) or `task` (legacy), `image_type (featured|desktop|mobile|in_article)`, `image_url/path`, prompt, status (`pending|generated|failed`), position. save() inherits account/site/sector from content/task. Indexes on content/task type/status/position.
|
|
- **ContentClusterMap** (summary): links content/tasks to clusters with roles (hub/supporting/attribute) and source (blueprint/manual/import); tracks keywords + slugs.
|
|
- **ContentTaxonomyRelation**: through table for content↔taxonomy.
|
|
|
|
## Serializers (modules/writer/serializers.py)
|
|
- **TasksSerializer**: requires cluster/content_type/content_structure on create; defaults status=queued; exposes cluster_name/sector_name; accepts site_id/sector_id (write-only).
|
|
- **ImagesSerializer**: exposes task_title/content_title; read-only account/timestamps.
|
|
- **ContentSerializer**: requires cluster/content_type/content_structure/title on create; defaults source=igny8, status=draft; exposes taxonomy terms, tags, categories, image flags/status; site_id/sector_id write-only.
|
|
- **ContentTaxonomySerializer** (in file but not shown above): manages taxonomy fields and external sync data.
|
|
- Group serializers for content images (`ContentImageSerializer`, `ContentImagesGroupSerializer`).
|
|
|
|
## ViewSets & Actions (modules/writer/views.py)
|
|
- **TasksViewSet** (`SiteSectorModelViewSet`):
|
|
- Filters/search/order: search title/keywords; filter status/cluster/content_type/structure; order by title/created_at/status.
|
|
- Bulk: `bulk_delete`, `bulk_update` (status).
|
|
- AI: `auto_generate_content` → `ContentGenerationService.generate_content(ids, account)`; limits 10 ids; returns task_id or sync result; 402 on `InsufficientCreditsError`.
|
|
- Create requires explicit `site_id` and `sector_id`; validates site/sector association; account resolved from request user/site.
|
|
- **ImagesViewSet**:
|
|
- Filters/order: filter task_id/content_id/image_type/status; order by created_at/position/id.
|
|
- Create enforces site/sector (from request context, falling back to user active site/default sector); sets account/site/sector.
|
|
- Actions:
|
|
- `serve_image_file` streams local file if `image_path` exists.
|
|
- `auto_generate_images` queues `run_ai_task(generate_images)` (Celery if available) for up to 10 task_ids.
|
|
- `bulk_update` sets status by `content_id` or `ids`.
|
|
- `content_images` returns grouped images (featured + in-article) via grouped serializer.
|
|
- **ContentViewSet** (not fully shown above but key actions):
|
|
- CRUD with filters/search/order (title, status, cluster, content_type/structure, source); tenant scoping via base class.
|
|
- Taxonomy management: add/remove terms, sync helpers (uses `ContentTaxonomy`).
|
|
- AI helpers: `generate_image_prompts` (queues `run_ai_task(generate_image_prompts)`), validation (`ContentValidationService`), metadata mapping (`MetadataMappingService`), content generation pathways tied to `ContentGenerationService`.
|
|
- Publishing: `publish` queues `publish_content_to_wordpress` Celery task (optimistically sets status=published), `wordpress_status` fetches WP status via integration, `unpublish` clears external links and reverts to draft.
|
|
- Image status helpers and grouped image retrieval also exposed.
|
|
- **ContentTaxonomyViewSet**: CRUD for categories/tags; supports external sync fields.
|
|
|
|
## Permissions, tenancy, throttling
|
|
- Permissions: `IsAuthenticatedAndActive` + `IsViewerOrAbove` across Writer; certain actions (e.g., `unpublish`) use `IsEditorOrAbove`.
|
|
- Tenancy: `SiteSectorModelViewSet` enforces account/site/sector scoping; create operations require site_id+sector_id or context site/sector; Images save derives account/site/sector from content/task.
|
|
- Throttling: `DebugScopedRateThrottle` with scope `writer`.
|
|
|
|
## AI/Background Tasks & Limits
|
|
- Content generation: `auto_generate_content` (max 10 task IDs) → `ContentGenerationService`; credits enforced (402 on insufficient).
|
|
- Image generation: `auto_generate_images` (max 10 task IDs) via `run_ai_task`; Celery preferred, sync fallback.
|
|
- Image prompt generation: `generate_image_prompts` via `run_ai_task`.
|
|
|
|
## Publishing Integration
|
|
- Publish: `/writer/content/{id}/publish/` → queues WordPress publish; refuses if already published.
|
|
- Status: `/writer/content/{id}/wordpress_status/` → checks WordPress via site integration.
|
|
- Unpublish: clears external_id/url, sets status to draft (does not delete WP post).
|
|
|
|
## CSV / Bulk Notes
|
|
- Tasks: bulk delete/update supported.
|
|
- Images: bulk status update by content or ids; grouped retrieval.
|
|
- Content: bulk operations primarily around AI prompt/image generation and publishing; no CSV import/export.
|
|
|
|
## Observations / gaps
|
|
- Tasks status choices limited to `queued/completed`; no explicit error/cancel states.
|
|
- Images bulk_update exposed on same ViewSet name as Tasks bulk_update (distinct routes under images vs tasks); OK but keep consistent naming.
|
|
- ContentViewSet file is large; ensure doc readers reference actions for validation/metadata mapping if extending.
|
|
|
|
|