From 5ba4603ac9619553d22a1d2b4f7e099c544f21ae Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Tue, 2 Dec 2025 19:39:08 +0100 Subject: [PATCH] refactor: remove Vendor.owner_user_id column MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove owner_user_id column and owner relationship from Vendor model - Update User model ownership checks to use company relationship - Add migration to drop owner_user_id column from vendors table Ownership is now determined solely via vendor.company.owner_user_id πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- DOCUMENTATION_MIGRATION_COMPLETE.md | 234 ------------------ ...4991_remove_vendor_owner_user_id_column.py | 60 +++++ models/database/user.py | 17 +- models/database/vendor.py | 7 - 4 files changed, 72 insertions(+), 246 deletions(-) delete mode 100644 DOCUMENTATION_MIGRATION_COMPLETE.md create mode 100644 alembic/versions/9f3a25ea4991_remove_vendor_owner_user_id_column.py diff --git a/DOCUMENTATION_MIGRATION_COMPLETE.md b/DOCUMENTATION_MIGRATION_COMPLETE.md deleted file mode 100644 index 6751d3ff..00000000 --- a/DOCUMENTATION_MIGRATION_COMPLETE.md +++ /dev/null @@ -1,234 +0,0 @@ -# Documentation Migration - COMPLETE βœ… - -**Date:** November 17, 2025 -**Status:** ALL CRITICAL CONTENT MIGRATED -**Action:** `docs/__REVAMPING/` folder can now be safely deleted - ---- - -## Summary - -All critical documentation has been successfully migrated from `docs/__REVAMPING/` to the main documentation structure. The documentation is now fully organized, branded as Wizamart, and ready for use. - ---- - -## βœ… What Was Migrated - -### 1. Letzshop β†’ Wizamart Branding Fixed -- βœ… `mkdocs.yml` - All branding updated -- βœ… `docs/development/environment-detection.md` - All references updated -- βœ… `docs/index.md` - Already updated -- βœ… Copyright updated to 2024-2025 - -### 2. Frontend Documentation (13 files) -**Location:** `docs/frontend/` - -- βœ… `overview.md` - Complete frontend architecture overview -- βœ… `shared/` - 6 files (UI components, pagination, sidebar, logging) -- βœ… `admin/` - 2 files (architecture, page templates) -- βœ… `vendor/` - 2 files (architecture, page templates) -- βœ… `shop/` - 2 files (architecture, page templates) - -### 3. Backend Documentation (2 files) -**Location:** `docs/backend/` - -- βœ… `admin-integration-guide.md` -- βœ… `admin-feature-integration.md` - -### 4. API Documentation & Diagrams (4 files) -**Location:** `docs/api/` - -- βœ… `authentication-flow-diagrams.md` ← Visual flow diagrams -- βœ… `rbac-visual-guide.md` ← RBAC visual diagrams - -### 5. Architecture Documentation & Diagrams (7 files) -**Location:** `docs/architecture/` - -**Diagrams:** -- βœ… `diagrams/multitenant-diagrams.md` -- βœ… `diagrams/vendor-domain-diagrams.md` - -**Theme System:** -- βœ… `theme-system/overview.md` -- βœ… `theme-system/presets.md` - -**URL Routing:** -- βœ… `url-routing/overview.md` - -### 6. Development Documentation (8 files) -**Location:** `docs/development/` - -- βœ… `environment-detection.md` (with all Letzshopβ†’Wizamart fixes) - -**Database Seeder:** -- βœ… `database-seeder/DATABASE_SEEDER_DOCUMENTATION.md` -- βœ… `database-seeder/MAKEFILE_DATABASE_SEEDER.md` -- βœ… `database-seeder/DATABASE_INIT_GUIDE.md` -- βœ… `database-seeder/DATABASE_QUICK_REFERENCE_GUIDE.md` - -**Error Rendering:** -- βœ… `error-rendering/ERROR_RENDERING_DEVELOPER_DOCUMENTATION.md` -- βœ… `error-rendering/HTML_ERROR_RENDERING_FLOW_DIAGRAM.md` - -### 7. Deployment Documentation (1 file) -**Location:** `docs/deployment/` - -- βœ… `stripe-integration.md` - Stripe payment integration guide - ---- - -## πŸ“Š Final Statistics - -**Total Files Migrated:** ~35+ documentation files -**New Directories Created:** 8 -- `docs/frontend/` (with 4 subdirectories) -- `docs/architecture/diagrams/` -- `docs/architecture/theme-system/` -- `docs/architecture/url-routing/` -- `docs/development/database-seeder/` -- `docs/development/error-rendering/` - -**mkdocs.yml Updates:** ~40+ new navigation entries added -**Build Status:** βœ… SUCCESS (no errors) - ---- - -## πŸ“ Final Documentation Structure - -``` -docs/ -β”œβ”€β”€ getting-started/ -β”œβ”€β”€ architecture/ -β”‚ β”œβ”€β”€ Overview, Multi-tenant, Middleware, Request Flow, Auth & RBAC -β”‚ β”œβ”€β”€ diagrams/ ✨ NEW -β”‚ β”‚ β”œβ”€β”€ multitenant-diagrams.md -β”‚ β”‚ └── vendor-domain-diagrams.md -β”‚ β”œβ”€β”€ theme-system/ ✨ NEW -β”‚ β”‚ β”œβ”€β”€ overview.md -β”‚ β”‚ └── presets.md -β”‚ └── url-routing/ ✨ NEW -β”‚ └── overview.md -β”œβ”€β”€ backend/ -β”‚ β”œβ”€β”€ Overview, Middleware Ref, RBAC Quick Ref -β”‚ β”œβ”€β”€ admin-integration-guide.md ✨ NEW -β”‚ └── admin-feature-integration.md ✨ NEW -β”œβ”€β”€ frontend/ ✨ NEW (Complete section) -β”‚ β”œβ”€β”€ overview.md -β”‚ β”œβ”€β”€ shared/ -β”‚ β”‚ β”œβ”€β”€ ui-components.md -β”‚ β”‚ β”œβ”€β”€ ui-components-quick-reference.md -β”‚ β”‚ β”œβ”€β”€ pagination.md -β”‚ β”‚ β”œβ”€β”€ pagination-quick-start.md -β”‚ β”‚ β”œβ”€β”€ sidebar.md -β”‚ β”‚ └── logging.md -β”‚ β”œβ”€β”€ admin/ -β”‚ β”‚ β”œβ”€β”€ architecture.md -β”‚ β”‚ └── page-templates.md -β”‚ β”œβ”€β”€ vendor/ -β”‚ β”‚ β”œβ”€β”€ architecture.md -β”‚ β”‚ └── page-templates.md -β”‚ └── shop/ -β”‚ β”œβ”€β”€ architecture.md -β”‚ └── page-templates.md -β”œβ”€β”€ api/ -β”‚ β”œβ”€β”€ Authentication (Guide, Quick Ref, Flow Diagrams ✨ NEW) -β”‚ β”œβ”€β”€ RBAC (Developer Guide, Visual Guide ✨ NEW) -β”‚ β”œβ”€β”€ Error Handling -β”‚ └── Rate Limiting -β”œβ”€β”€ guides/ -β”œβ”€β”€ testing/ -β”œβ”€β”€ development/ -β”‚ β”œβ”€β”€ Icons, Naming Conventions, Database Migrations -β”‚ β”œβ”€β”€ database-seeder/ ✨ NEW -β”‚ β”‚ β”œβ”€β”€ DATABASE_SEEDER_DOCUMENTATION.md -β”‚ β”‚ β”œβ”€β”€ MAKEFILE_DATABASE_SEEDER.md -β”‚ β”‚ β”œβ”€β”€ DATABASE_INIT_GUIDE.md -β”‚ β”‚ └── DATABASE_QUICK_REFERENCE_GUIDE.md -β”‚ β”œβ”€β”€ Exception Handling, Frontend Exception Handling -β”‚ β”œβ”€β”€ error-rendering/ ✨ NEW -β”‚ β”‚ β”œβ”€β”€ ERROR_RENDERING_DEVELOPER_DOCUMENTATION.md -β”‚ β”‚ └── HTML_ERROR_RENDERING_FLOW_DIAGRAM.md -β”‚ β”œβ”€β”€ environment-detection.md (βœ… Wizamart branding fixed) -β”‚ β”œβ”€β”€ Contributing -β”‚ └── PyCharm Setup -└── deployment/ - β”œβ”€β”€ Overview, Docker, Production, Environment Variables - └── stripe-integration.md ✨ NEW -``` - ---- - -## πŸ—‘οΈ What's Left in __REVAMPING (Can Be Deleted) - -The `docs/__REVAMPING/` folder now only contains: - -1. **Duplicates** - Already migrated files -2. **Roadmaps** - Historical project roadmaps (already completed work) -3. **Old project docs** - Superseded by current documentation -4. **Migration tracking** - `MIGRATION_STATUS.md` (kept for reference) - -**Recommendation:** The entire `docs/__REVAMPING/` folder can now be safely deleted. - ---- - -## βœ… Verification Checklist - -- βœ… All Letzshop references fixed (except marketplace imports context) -- βœ… All diagrams migrated -- βœ… All frontend documentation migrated -- βœ… All backend documentation migrated -- βœ… All architecture documentation migrated -- βœ… Database seeder docs migrated -- βœ… Error rendering docs migrated -- βœ… Theme system docs migrated -- βœ… URL routing docs migrated -- βœ… Stripe integration docs migrated -- βœ… mkdocs.yml updated with all new files -- βœ… Documentation builds successfully -- βœ… No critical content left unmigrated - ---- - -## 🎯 Next Steps - -1. **Review** - Quick review of migrated docs for any remaining Letzshop references -2. **Delete** - Remove `docs/__REVAMPING/` folder -3. **Commit** - Commit all changes to git -4. **Deploy** - Build and deploy documentation with `mkdocs serve` or `mkdocs build` - ---- - -## πŸ“ Git Status - -New files to add to git: -``` -docs/api/authentication-flow-diagrams.md -docs/api/rbac-visual-guide.md -docs/architecture/diagrams/ -docs/architecture/theme-system/ -docs/architecture/url-routing/ -docs/backend/admin-integration-guide.md -docs/backend/admin-feature-integration.md -docs/development/database-seeder/ -docs/development/error-rendering/ -docs/development/environment-detection.md -docs/deployment/stripe-integration.md -docs/frontend/ (entire directory) -mkdocs.yml (modified) -``` - ---- - -## πŸŽ‰ SUCCESS! - -The documentation migration is **100% complete**. The Wizamart platform now has: - -- βœ… Comprehensive, well-organized documentation -- βœ… Proper branding throughout -- βœ… Complete frontend, backend, and architecture guides -- βœ… All diagrams and visual guides included -- βœ… Database seeder and error rendering documentation -- βœ… Theme system and URL routing guides -- βœ… Stripe integration guide for future implementation - -**The `docs/__REVAMPING/` folder can now be safely deleted.** diff --git a/alembic/versions/9f3a25ea4991_remove_vendor_owner_user_id_column.py b/alembic/versions/9f3a25ea4991_remove_vendor_owner_user_id_column.py new file mode 100644 index 00000000..98c9ffa6 --- /dev/null +++ b/alembic/versions/9f3a25ea4991_remove_vendor_owner_user_id_column.py @@ -0,0 +1,60 @@ +"""remove_vendor_owner_user_id_column + +Revision ID: 9f3a25ea4991 +Revises: 5818330181a5 +Create Date: 2025-12-02 17:58:45.663338 + +This migration removes the owner_user_id column from the vendors table. + +Architecture Change: +- OLD: Each vendor had its own owner (vendor.owner_user_id) +- NEW: Vendors belong to a company, company has one owner (company.owner_user_id) + +The vendor ownership is now determined via the company relationship: +- vendor.company.owner_user_id contains the owner +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = '9f3a25ea4991' +down_revision: Union[str, None] = '5818330181a5' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """ + Remove owner_user_id column from vendors table. + + Ownership is now determined via the company relationship. + + Note: SQLite batch mode recreates the table without the column, + so we don't need to explicitly drop constraints. + """ + with op.batch_alter_table('vendors', schema=None) as batch_op: + # Drop the column - batch mode handles constraints automatically + batch_op.drop_column('owner_user_id') + + +def downgrade() -> None: + """ + Re-add owner_user_id column to vendors table. + + WARNING: This will add the column back but NOT restore the data. + You will need to manually populate owner_user_id from company.owner_user_id + if reverting this migration. + """ + with op.batch_alter_table('vendors', schema=None) as batch_op: + batch_op.add_column( + sa.Column('owner_user_id', sa.Integer(), nullable=True) + ) + batch_op.create_foreign_key( + 'vendors_owner_user_id_fkey', + 'users', + ['owner_user_id'], + ['id'] + ) diff --git a/models/database/user.py b/models/database/user.py index 6dcb7a86..803efa00 100644 --- a/models/database/user.py +++ b/models/database/user.py @@ -51,7 +51,6 @@ class User(Base, TimestampMixin): "MarketplaceImportJob", back_populates="user" ) owned_companies = relationship("Company", back_populates="owner") - owned_vendors = relationship("Vendor", back_populates="owner") vendor_memberships = relationship( "VendorUser", foreign_keys="[VendorUser.user_id]", back_populates="user" ) @@ -78,12 +77,20 @@ class User(Base, TimestampMixin): return self.role == UserRole.VENDOR.value def is_owner_of(self, vendor_id: int) -> bool: - """Check if user is the owner of a specific vendor.""" - return any(v.id == vendor_id for v in self.owned_vendors) + """ + Check if user is the owner of a specific vendor. + + Ownership is determined via company ownership: + User owns Company β†’ Company has Vendor β†’ User owns Vendor + """ + for company in self.owned_companies: + if any(v.id == vendor_id for v in company.vendors): + return True + return False def is_member_of(self, vendor_id: int) -> bool: """Check if user is a member of a specific vendor (owner or team).""" - # Check if owner + # Check if owner (via company) if self.is_owner_of(vendor_id): return True # Check if team member @@ -93,7 +100,7 @@ class User(Base, TimestampMixin): def get_vendor_role(self, vendor_id: int) -> str: """Get user's role within a specific vendor.""" - # Check if owner + # Check if owner (via company) if self.is_owner_of(vendor_id): return "owner" diff --git a/models/database/vendor.py b/models/database/vendor.py index 88a98cdc..adf9c011 100644 --- a/models/database/vendor.py +++ b/models/database/vendor.py @@ -50,10 +50,6 @@ class Vendor(Base, TimestampMixin): name = Column(String, nullable=False) # Non-nullable name column for the vendor (brand name) description = Column(Text) # Optional text description column for the vendor - owner_user_id = Column( - Integer, ForeignKey("users.id"), nullable=True - ) # Foreign key to user ID of the vendor's owner (DEPRECATED - use company.owner_user_id instead) - # Letzshop URLs - multi-language support (brand-specific marketplace feeds) letzshop_csv_url_fr = Column(String) # URL for French CSV in Letzshop letzshop_csv_url_en = Column(String) # URL for English CSV in Letzshop @@ -73,9 +69,6 @@ class Vendor(Base, TimestampMixin): company = relationship( "Company", back_populates="vendors" ) # Relationship with Company model for the parent company - owner = relationship( - "User", back_populates="owned_vendors" - ) # Relationship with User model for the vendor's owner (legacy) vendor_users = relationship( "VendorUser", back_populates="vendor" ) # Relationship with VendorUser model for users in this vendor