Files
igny8/original-specs of-refactor
2025-11-26 06:08:44 +05:00

687 lines
10 KiB
Plaintext

0. GOAL
When this refactor is complete:
You enter keywords in Planner.
Clusters and ideas are created.
Writer generates tasks and content.
Content Manager becomes the single source of truth.
One click publish sends content to WordPress.
All mappings (cluster, taxonomies, site) are correct.
Linker, Optimizer, IGNY8 hosted sites stay out of scope for now.
This spec assumes all earlier decisions you made about models and statuses are final.
1. END TO END FLOW (KEYWORD TO PUBLISH)
1.1 High level flow
Planner
Input keywords
Generate clusters
Generate ideas per cluster
Convert ideas into Writer tasks
Writer
Tasks created with content_type and content_structure
AI generates draft content
Task marked completed
Content saved as draft entry
Content Manager
Lists all content for a site (imported and AI written)
You edit, assign cluster and taxonomies if needed
You click publish for selected content
Publish to WordPress
IGNY8 sends content HTML and metadata to WP via REST
WP creates or updates post / page / product
WP returns ID and URL
IGNY8 saves external_id and external_url
Content status goes from draft to published
Task status already completed when content was generated
Only Content has draft/published.
Only Task has queued/completed.
Planner and Writer do not track sync.
2. BACKEND DATA MODEL (FINAL)
This is the corrected model set the whole system is built on.
2.1 Cluster
Pure topic. Parent of everything else.
Not tied to a content type.
Fields:
id
site
sector
name
description
created_at
updated_at
Remove: context_type, dimension_meta.
2.2 Task
Planner → Writer contract for content creation.
Fields:
id
site
sector
cluster (FK → Cluster, required)
content_type (Article, Page, Product, Taxonomy)
content_structure (Review, Comparison, Tutorial, Listicle, Landing Page, Archive Page, etc)
taxonomy_term (FK → ContentTaxonomy, optional, used when targeting a taxonomy archive)
keywords (M2M → Keyword)
status (queued, completed)
created_at
updated_at
Remove: cluster_role, sync_status.
2.3 Content
Writer output and imported WP content, managed in Content Manager.
Fields:
id
site
sector
cluster (FK → Cluster, required)
content_type (Article, Page, Product, Taxonomy)
content_structure
title
content_html
taxonomy_terms (M2M → ContentTaxonomy)
external_id (WP post_id, nullable)
external_url (WP permalink, nullable)
status (draft, published)
source (igny8, wordpress)
created_at
updated_at
Remove: cluster_role, sync_status.
2.4 ContentTaxonomy
WordPress taxonomies and IGNY8 cluster-like taxonomies.
Fields:
id
site
sector
name
slug
taxonomy_type (category, tag, product_category, product_attribute, cluster, service_category if you keep it)
external_taxonomy (WP taxonomy slug, e.g. category, post_tag, product_cat, pa_size; null for cluster)
external_id (WP term_id; null for igy8 custom terms and clusters)
created_at
updated_at
Remove: sync_status.
3. WORDPRESS ↔ IGNY8 DATA FLOWS
3.1 WordPress → IGNY8 (import / sync)
Plugin endpoints
WordPress plugin provides:
/wp-json/igny8/v1/site-metadata
/wp-json/igny8/v1/posts
/wp-json/igny8/v1/taxonomies
Possibly specific endpoints like /post-by-task-id, /post-by-content-id
Plugin responsibilities:
Export posts, pages, products with:
post_id
post_type
post_title
post_content
permalink
taxonomies (term_ids + taxonomy slugs)
meta keys for any IGNY8 links (optional)
Export taxonomies:
term_id
name
slug
taxonomy
IGNY8 backend behaviour
When importing posts:
Create Content rows:
site, sector inferred from site record
cluster: null initially (to be assigned later)
content_type mapped from WP post_type:
post ⇒ Article
page ⇒ Page
product ⇒ Product
content_structure: optional default (e.g. ImportedArticle, ImportedPage)
title, content_html from WP
external_id = post_id
external_url = permalink
status = draft
source = wordpress
Link taxonomy terms:
For each term on the WP post:
upsert ContentTaxonomy by external_id + external_taxonomy
attach to Content.taxonomy_terms
When importing taxonomies:
For each WP term:
Create ContentTaxonomy if it does not exist:
name
slug
taxonomy_type derived from taxonomy (category, tag, product_category, product_attribute)
external_taxonomy = WP taxonomy slug
external_id = term_id
No sync_status is needed.
Imported items are identified by source=wordpress and external_id present.
3.2 IGNY8 → WordPress (publish)
Publishing is done only from Content Manager, not from Planner or Writer.
Backend publishing service
Given a Content id:
Load Content:
ensure status = draft
ensure site record configured with WP endpoint and auth
Prepare payload:
post_type based on content_type
post_title from Content.title
post_content from Content.content_html
tax_input from Content.taxonomy_terms mapped through external_taxonomy and external_id
Call WordPress REST:
POST /wp-json/wp/v2/{post_type}
On success:
response.id ⇒ Content.external_id
response.link ⇒ Content.external_url
Content.status ⇒ published
Do not touch Task; Task was marked completed when content was generated.
If the Content row already has an external_id, publishing should update that post instead of creating a new one.
WordPress plugin side
Accept incoming POST from IGNY8:
Validate token / key
Create or update the post:
set post_title, post_content, post_type, post_status=publish
set taxonomies based on term IDs
Return:
id
link
Plugin may optionally store meta keys like _igny8_content_id or _igny8_cluster_id, but this is optional.
4. CONTENT MANAGER AS SOURCE OF TRUTH
Content Manager is the last part of the flow.
4.1 Role
Content Manager:
Shows all content for a site:
imported from WP
generated by Writer
Allows editing and assigning:
cluster
taxonomy_terms
Controls publish to WordPress.
Reflects the final status for each content item:
draft
published
All other modules are upstream.
They feed into Content Manager, but do not override its status.
4.2 Content Manager data model usage
Content listing uses:
Content.id
Content.title
Content.content_type
Content.content_structure
Content.cluster
Content.taxonomy_terms
Content.status
Content.external_id
Content.external_url
Content.source
Content.created_at / updated_at
4.3 Content Manager UX requirements
Table columns:
Title
Type (Article / Page / Product / Taxonomy)
Structure (Review, Landing Page, Archive Page, etc)
Cluster (with link to cluster detail)
Taxonomies (comma separated list of taxonomy term names)
Status (draft/published)
Source (IGNY8, WordPress)
URL (clickable if published)
Actions (Edit, Publish, View in WordPress)
Filters:
content_type
status
cluster
taxonomy_type (optional)
source
Row actions:
Edit:
Opens editor on Content:
edit title
edit content_html
attach or change cluster
attach or change taxonomy_terms
Publish:
Calls backend publish service
On success:
status becomes published
external_id and external_url are filled
View in WordPress:
Opens external_url in new tab
4.4 Cluster and taxonomy assignment rules
New content generated from tasks:
cluster is assigned automatically from the Task.cluster
taxonomy_terms can be empty initially
Imported content from WordPress:
cluster must be manually assigned in Content Manager or via auto mapping later
taxonomy_terms are imported automatically
Content Manager must allow:
batch cluster assignment:
select multiple rows
assign one cluster
batch taxonomy assignment:
select rows
attach a taxonomy term
5. FRONTEND MODULES ALIGNED WITH THIS FLOW
5.1 Planner
Key UI responsibilities:
Keywords input and cluster generation
Idea generation per cluster
Create tasks that are passed to Writer
Data it needs to pass to Writer:
cluster_id
content_type
content_structure
primary_keyword
any extra parameters (tone, target country etc)
5.2 Writer
Key UI responsibilities:
List tasks with status (queued/completed)
For each task:
show cluster
content_type
content_structure
primary_keyword
Actions:
Generate draft content
View generated draft
Writer does not publish and does not talk to WordPress directly.
5.3 Sites
For this DDAY refactor, keep only:
grid view of sites
for each site card:
Dashboard button
Content Manager button
Settings button
Active/inactive toggle at the top
Remove:
Pages button and its backend logic
Sectors button from card (moved into Site Settings tab)
Site builder and blueprints buttons (out of scope)
The Content Manager for a site is reachable from the site card.
5.4 Cluster Detail Page
When clicking a cluster:
Show:
cluster name and description
tabs or sections per content_type:
Articles
Pages
Products
Taxonomy Pages
each section listing content entries linked to that cluster
This view can internally reuse the Content Manager data but filtered by cluster.
6. STATE MACHINE SUMMARY
6.1 Task
queued:
created from Planner or manually
completed:
AI content generated and saved to Content table
Task never changes when publish happens.
6.2 Content
draft:
created from Writer completion or from WordPress import
published:
after successful publish to WordPress
There is no separate sync_status in this refactor.
If external_id is present and status is published, it is live.
7. IMPLEMENTATION CHECKLIST
To actually complete this DDAY refactor:
Backend
Update models:
Remove fields: cluster_role, sync_status, context_type, dimension_meta, ContentTaxonomy.sync_status
Add or rename fields: taxonomy_term on Task, taxonomy_terms M2M on Content if not already consistent
Regenerate migrations.
Update serializers:
Remove removed fields
Add or rename fields accordingly
Review all viewsets and services:
Task creation and listing
Content creation, listing, edit
WordPress import service
WordPress publish service
Confirm WordPress plugin endpoints match expected payloads.
Frontend
Planner:
Ensure ideas create tasks with cluster_id, content_type, content_structure.
Writer:
Only show queued/completed status.
No sync related fields.
Link to open draft in Content Manager (optional but helpful).
Sites:
Remove builder-related buttons.
Only show Dashboard, Content, Settings.
Move toggle and sectors UI as per your earlier 18 points.
Content Manager:
Implement table with final columns and filters.
Implement Edit and Publish actions as defined.
Ensure every content row came from Content model only.
Integrate cluster and taxonomy selectors.
Cluster detail:
Filter Content list by cluster_id and group by content_type