diff --git a/agent/analysis/ARCHITECTURE.md b/agent/analysis/ARCHITECTURE.md new file mode 100644 index 0000000..ba7d99b --- /dev/null +++ b/agent/analysis/ARCHITECTURE.md @@ -0,0 +1,103 @@ +# Target Architecture + +This document outlines the proposed architecture for the rebuilt Nail Studio SaaS application. The design is guided by the decisions made in the `TRUTH_TABLE.md` and aims to address the shortcomings of the original implementation. + +## 1. Guiding Principles + +- **Clarity over Cleverness:** The new architecture will prioritize readability and maintainability. +- **Single Source of Truth (SSOT):** Every piece of business logic and data should have one, and only one, authoritative home. +- **Service-Oriented:** Business logic will be decoupled from the web framework (Flask) and data layer (SQLAlchemy) where possible. +- **Testability:** The architecture must be easy to test, with clear separation between components. + +## 2. Core Components + +The application will be structured into three primary layers: the **Web Layer**, the **Service Layer**, and the **Data Layer**. + +### 2.1. Web Layer (Flask) + +- **Responsibility:** Handling HTTP requests and responses. This layer should contain minimal business logic. +- **Structure:** + - **Blueprints:** The existing blueprint structure will be retained and reinforced. Each blueprint will handle a specific domain (e.g., `transactions`, `users`, `reports`). + - **Routes (`routes.py`):** Route functions will be responsible for: + 1. Parsing incoming request data (e.g., from forms or JSON bodies). + 2. Calling the appropriate **Service Layer** function(s) to perform business operations. + 3. Handling authorization checks via a unified decorator. + 4. Rendering templates or returning JSON responses based on the results from the Service Layer. + - **Forms (`forms.py`):** WTForms will continue to be used for server-side validation. + +### 2.2. Service Layer (New) + +- **Responsibility:** This is the heart of the new architecture. It will contain all the business logic that was previously scattered between model properties and route functions. +- **Structure:** + - A new `app/services` directory will be created. + - Each service will be a Python class or module focused on a specific domain. + - **Example Services:** + - `SalaryService`: Will contain the unified logic for calculating master salaries, handling all modes (`percent`, `fixed`, `mixed`). This fixes the "Badly Implemented Domain Truth" identified in the Truth Table. + - `ReportingService`: Will generate complex reports by querying the data layer. + - `TransactionService`: Will handle the creation, modification, and deletion of transactions, ensuring all related business rules are followed. +- **Benefits:** + - **Decoupling:** The business logic is no longer tied to Flask routes or SQLAlchemy models. + - **Testability:** Services can be unit-tested in isolation, without needing a full web request context. + - **Reusability:** The same service can be used by web routes, background jobs, or command-line scripts. + +### 2.3. Data Layer (SQLAlchemy) + +- **Responsibility:** Defining the structure of the data and interacting with the database. +- **Structure:** + - **Models (`app/models`):** SQLAlchemy models will be treated as pure data containers. + - They will contain table definitions, columns, and relationships. + - **NO business logic.** Properties like `Transaction.master_salary` will be removed and their logic moved to the `SalaryService`. + - Helper properties for simple formatting (e.g., `total_amount`) are acceptable. + - **Repositories (Optional but Recommended):** For more complex queries, the Repository Pattern can be introduced to encapsulate data access logic, further separating the Service Layer from direct SQLAlchemy query syntax. + +## 3. Key Architectural Decisions + +### 3.1. Unified Authorization System + +- The legacy `role` string on the `User` model will be **eliminated**. +- The system will rely **exclusively** on the `Role` and `Permission` models. +- A custom Flask decorator (e.g., `@permission_required('edit_transaction')`) will be created to enforce permissions at the route level, making access control explicit and easy to audit. + +### 3.2. Configuration and Initialization + +- The `create_app` factory pattern will be maintained. +- Environment variables will be the primary method for configuration to follow 12-Factor App principles. + +### 3.3. Refined Data Models + +- **`Source` Model:** Will be updated with a boolean flag `is_smm_source` to replace the hardcoded string matching, as decided in the Truth Table. +- All models will be reviewed for clarity and normalization. + +## 4. Diagram of Proposed Architecture + +``` ++------------------------------------------------------------------+ +| Web Layer (Flask Blueprints) | +|------------------------------------------------------------------| +| - Handles HTTP Requests/Responses | +| - Validates Input (Forms) | +| - Calls Service Layer for business logic | +| - Renders Templates / Returns JSON | +| - Enforces Permissions with Decorators | +| (@permission_required) | ++--------------------------+---------------------------------------+ + | + v ++--------------------------+---------------------------------------+ +| Service Layer (Plain Python) | +|------------------------------------------------------------------| +| - Contains all Business Logic (e.g., SalaryService) | +| - Orchestrates Data Layer operations | +| - Decoupled from Web and Data specifics | +| - Highly Testable | ++--------------------------+---------------------------------------+ + | + v ++--------------------------+---------------------------------------+ +| Data Layer (SQLAlchemy Models) | +|------------------------------------------------------------------| +| - Defines Data Schema (Tables, Columns, Relationships) | +| - Models are simple data containers (no business logic) | +| - (Optional) Repositories for complex query encapsulation | ++------------------------------------------------------------------+ +``` diff --git a/agent/analysis/DOMAIN_MAP.md b/agent/analysis/DOMAIN_MAP.md new file mode 100644 index 0000000..701507f --- /dev/null +++ b/agent/analysis/DOMAIN_MAP.md @@ -0,0 +1,73 @@ +# Domain Map + +This document outlines the core business concepts (the domain) of the Nail Studio application, derived from the existing codebase. + +## 1. Core Entities + +### 1.1. Transaction +- **Description:** The central and most important entity in the system. It represents a single customer visit or sale. +- **Key Attributes:** Date, Master, Services Rendered, Items Sold, Total Amount, Payment Method, Client Source. +- **Relationships:** + - Belongs to one `Master`. + - Can have many `Services`. + - Can have many `TransactionItems` (products sold). + - Belongs to one `Source`. + - Belongs to one `PaymentMethod`. + +### 1.2. Master +- **Description:** An employee who performs services for clients (e.g., a nail technician). They are the primary revenue generators. +- **Key Attributes:** Name, Commission Percent (for services), Sales Commission Percent (for products), Salary Mode (`percent`, `fixed`, `mixed`), Fixed Daily Rate. +- **Relationships:** + - Can have many `Transactions`. + - Can be linked to one `User` account for system access. + +### 1.3. User & Access Control +- **Description:** An individual who can log in to the application. Their access is governed by roles and permissions. +- **Key Concepts:** + - **User:** The login account (username, password). + - **Role:** A template defining a set of permissions (e.g., "Senior Admin", "Master", "SMM"). + - **Permission:** A specific right to perform an action (e.g., "view_financial_reports", "edit_users"). +- **Relationships:** + - A `User` has one `Role`. + - A `Role` grants multiple `Permissions`. + - A `User`'s permissions can be individually overridden. + - A `User` can be linked to one `Master` profile. +- **Note:** The system currently has a hybrid implementation, with both a simple `role` string and a more structured `Role`/`Permission` model. + +### 1.4. Financial & Inventory Entities +- **Service:** A specific service offered by the studio (e.g., "Gel Manicure"). It has a price. +- **Shelf Item / Transaction Item:** A physical product sold by the studio. `ShelfItem` is the catalog entry, and `TransactionItem` is the instance of that item within a `Transaction`. +- **Expense:** A record of a business cost (e.g., rent, supplies). It has an amount, date, and category. +- **Daily Balance:** A record of the cash on hand at the beginning of a business day. + +### 1.5. Supporting Entities (Parameters) +- **Source:** The source of a client (e.g., "Instagram", "Walk-in"). Used for marketing analytics and commission calculations. +- **Payment Method:** How a transaction was paid for (e.g., "Cash", "Card"). Can have an associated fee. +- **Expense Category:** A category for an `Expense` (e.g., "Rent", "Supplies"). +- **Discount Reason:** The reason a discount was applied to a transaction. + +## 2. Core Business Processes + +### 2.1. Recording a Transaction +- An administrator or master records a client visit. +- They select the `Master`, the `Services` performed, and any `ShelfItems` sold. +- They input the payment details (`PaymentMethod`, amount, discounts). +- The system saves this as a `Transaction`. + +### 2.2. Master Salary Calculation +- This is a critical and complex process. +- The salary is calculated per-`Transaction`. +- The logic depends on the `Master.salary_mode`: + - **Percent:** `Transaction.real_amount * Master.commission_percent` + commissions from product sales. + - **Fixed:** A flat `Master.fixed_daily_rate` is applied (logic for this seems to be in reporting, not the model). + - **Mixed:** A combination of the fixed rate and percentage-based commissions. +- The `Transaction.master_salary` property calculates the percentage-based portion for a single transaction. + +### 2.3. Financial Reporting +- The system generates reports based on aggregated `Transaction` and `Expense` data. +- Key metrics include: Total Income, Total Expenses, Net Profit, Average Check. +- Reports are often filtered by date ranges and can be specific to a `Master`. + +### 2.4. User Access Management +- Users are assigned roles that restrict their view and actions. +- For example, a `Master` can only see their own transactions and salary, while an `Owner` can see all financial data. diff --git a/agent/analysis/PROJECT_SCAN.md b/agent/analysis/PROJECT_SCAN.md new file mode 100644 index 0000000..b310985 --- /dev/null +++ b/agent/analysis/PROJECT_SCAN.md @@ -0,0 +1,45 @@ +# Project Scan + +## 1. Overview + +This document provides a high-level technical overview of the existing Nail Studio project. The analysis is based on a static examination of the repository's file structure, key source code files, and configuration. + +## 2. Core Technology Stack + +- **Backend Framework:** Flask +- **Database ORM:** Flask-SQLAlchemy +- **Authentication:** Flask-Login +- **Forms:** Flask-WTF +- **Database Migrations:** Flask-Migrate +- **Dependencies:** Key libraries include `qrcode`, `pillow`, `pytest`, and `waitress`. All dependencies are listed in `requirements.txt`. + +## 3. Project Structure + +The project follows a modular, blueprint-based architecture. + +- **`run.py`**: The main entry point for the application. It initializes the Flask app and runs it. +- **`config.py`**: Contains application configuration, including database URIs and default credentials. +- **`app/`**: The main application package. + - **`__init__.py`**: Contains the `create_app` factory function, which initializes extensions and registers blueprints. + - **`models/`**: Defines all SQLAlchemy database models. This is the source of truth for the data structure. + - **`main/`**: The main blueprint, containing the primary dashboard route (`/`). + - **`auth/`**: Handles user authentication (login, logout). + - **`transactions/`, `expenses/`, `reports/`, etc.**: Feature-specific blueprints, each containing its own routes and logic. + - **`forms/`**: Contains WTForms definitions for data validation and input. + - **`utils.py`**: Utility functions, including database initialization logic. +- **`migrations/`**: Contains database migration scripts generated by Flask-Migrate. +- **`templates/`**: Contains Jinja2 HTML templates for the user interface. +- **`tests/`**: Contains application tests (structure suggests Pytest). +- **`Dockerfile`, `docker-compose.yml`, `render.yaml`**: Files indicating support for containerization (Docker) and deployment on cloud platforms (Render). + +## 4. Key Architectural Observations + +- **Modular Design:** The use of Flask Blueprints is a good architectural choice, separating concerns by feature. +- **Centralized Models:** All data models are defined within the `app/models` package, providing a clear and centralized view of the data schema. +- **Hybrid Auth System:** The `app/models/user.py` file reveals a hybrid authentication/authorization system. It includes both a legacy string-based `role` field and a more robust, newer system based on `Role` and `Permission` models with JSON-based permission overrides. This indicates a system in transition. +- **Business Logic in Models:** Critical business logic, such as the `master_salary` calculation, is implemented as a property within the `Transaction` model. This is a common pattern but can lead to complex models. +- **Database:** The project is configured to use a database managed by SQLAlchemy and Flask-Migrate, which is standard for Flask applications. + +## 5. Initial Assessment + +The project is a non-trivial Flask application with a solid, if partially refactored, foundation. The blueprint structure is sound, but the hybrid nature of the permission system is a key area of complexity that needs to be addressed in the rebuild. The domain logic appears to be deeply embedded within the ORM models. diff --git a/agent/analysis/TRUTH_TABLE.md b/agent/analysis/TRUTH_TABLE.md new file mode 100644 index 0000000..258b9b1 --- /dev/null +++ b/agent/analysis/TRUTH_TABLE.md @@ -0,0 +1,18 @@ +# Truth Table + +This table classifies each major concept from the old project to determine its business value and decide its fate in the new system. + +| Concept | Where It Appears | Why It Exists (Business Explanation) | Classification | Decision & Justification | +| :--- | :--- | :--- | :--- | :--- | +| **Transaction** | `app/models/transaction.py` | Represents a client visit or sale, the fundamental unit of revenue. | CORE DOMAIN TRUTH | **KEEP.** This is the central entity of the entire application. | +| **Master** | `app/models/master.py` | Represents a service provider (employee) who generates revenue. | CORE DOMAIN TRUTH | **KEEP.** Essential for tracking sales, services, and calculating salaries. | +| **Master Salary Calculation (in model)** | `Transaction.master_salary` property | To calculate the percentage-based portion of a master's pay for a single transaction. | DOMAIN TRUTH, BADLY IMPLEMENTED | **REWRITE.** The logic is domain truth, but its implementation is incomplete and misplaced. It only handles the percentage part, ignoring the fixed-rate salary, which is handled elsewhere (in reports). The new system must have a unified, single source of truth for all salary calculations, likely in a dedicated service layer, not the model property. | +| **Hybrid RBAC System** | `app/models/user.py` (legacy `role` field vs. new `Role`/`Permission` models) | The system evolved from a simple role string to a more flexible permissions model, but the old system was never fully removed. | ARCHITECTURAL ERROR | **REWRITE.** The existence of two parallel systems for authorization is a major source of confusion and potential bugs. The new system will use **only** the structured `Role` and `Permission` models. The legacy `role` string will be dropped entirely after a data migration. | +| **User-Master Link** | `User.master_id` foreign key | To connect a user's login account to their employee profile, allowing masters to log in and see their own stats. | CORE DOMAIN TRUTH | **KEEP.** This is a critical link for role-based access control and personal dashboards. | +| **Service** | `app/models/params.py` | Defines a service that can be sold (e.g., "Manicure"). | CORE DOMAIN TRUTH | **KEEP.** A fundamental part of a transaction. | +| **Shelf Item / Product Sale** | `app/models/inventory.py`, `app/models/transaction.py` | Represents physical goods that can be sold, with their own commission structures. | CORE DOMAIN TRUTH | **KEEP.** Represents a distinct and important revenue stream for the business. | +| **Expense Tracking** | `app/models/finance.py` | To record business expenses for profit/loss calculation. | CORE DOMAIN TRUTH | **KEEP.** Essential for any financial accounting. | +| **Client Source Tracking** | `app/models/params.py` | To track marketing channels (e.g., Instagram, Walk-in) and calculate potential commissions for partners. | CORE DOMAIN TRUTH | **KEEP.** Provides valuable business intelligence for marketing efforts. | +| **Daily Balance** | `app/models/finance.py` | To track the opening cash balance for the day. | CORE DOMAIN TRUTH | **KEEP.** A standard and necessary feature for daily cash flow management. | +| **Hardcoded SMM Logic** | `app/main/routes.py` (line 80, `Source.name.ilike('%инст%')`) | To identify new clients coming from specific social media sources for SMM dashboards. | TEMPORARY WORKAROUND | **REWRITE.** This is a brittle, temporary solution. The domain truth is "tracking SMM performance," but the implementation is poor. The new system should use a more robust mechanism, like a dedicated `is_smm_source` boolean flag or a tag system on the `Source` model, to avoid hardcoded strings in business logic. | +| **Soft Deletes** | `SoftDeleteMixin` in `app/models/base.py` | To allow data to be "deleted" without actually removing it from the database, preserving historical integrity. | CORE DOMAIN TRUTH | **KEEP.** This is a critical business requirement for a system of record, preventing accidental data loss and preserving audit trails. | diff --git a/agent/checklists/REBUILD_CHECKLIST.md b/agent/checklists/REBUILD_CHECKLIST.md new file mode 100644 index 0000000..f1b64a0 --- /dev/null +++ b/agent/checklists/REBUILD_CHECKLIST.md @@ -0,0 +1,75 @@ +# Rebuild Checklist + +This checklist outlines the high-level steps for the implementation phase of the Nail Studio application rebuild. It is based on the analysis and decisions documented in the `/agent` workspace. + +## Phase 1: Foundation & Data Layer Refactoring + +- [ ] **1.1. Setup Core Application Structure:** + - [ ] Initialize the new `app/services` directory. + - [ ] Verify the Flask `create_app` factory is clean and ready. + +- [ ] **1.2. Refactor Data Models:** + - [ ] Go through every model in `app/models`. + - [ ] **Remove all business logic properties**, most notably `Transaction.master_salary`. Models should only contain schema definitions, relationships, and simple helper properties. + - [ ] Add the `is_smm_source: bool` field to the `Source` model. + +- [ ] **1.3. Implement RBAC Data Migration:** + - [ ] Generate a new database migration script using `flask db migrate`. + - [ ] In the script, write Python code to: + - [ ] Iterate through all `User` records. + - [ ] Read the legacy `role` string. + - [ ] Find the corresponding `Role` object by its `slug`. + - [ ] Assign the `Role` object to the `user.role_obj` relationship. + - [ ] **After** the data migration is proven to work, generate a *new* migration to drop the `User.role` column. + +## Phase 2: Service Layer & Business Logic + +- [ ] **2.1. Implement Salary Service:** + - [ ] Create `app/services/salary_service.py`. + - [ ] Implement a `SalaryService` class or module. + - [ ] Create the method `calculate_salary_for_period(master, start_date, end_date)` which contains the unified logic to handle `percent`, `fixed`, and `mixed` salary modes correctly. + +- [ ] **2.2. Implement Other Core Services:** + - [ ] Create `app/services/transaction_service.py` to handle transaction creation and management. + - [ ] Create `app/services/reporting_service.py` to encapsulate the logic for generating reports. + +## Phase 3: Web Layer & Authorization + +- [ ] **3.1. Implement Unified Permission System:** + - [ ] Create a decorator `@permission_required('permission_slug')` that checks `current_user.has_permission()`. + - [ ] Remove all legacy property checks like `if current_user.is_admin` from the entire codebase (routes and templates). + - [ ] Replace them with the new `user.has_permission('slug')` method or the decorator. + +- [ ] **3.2. Refactor Routes to Use Service Layer:** + - [ ] Go through every route function in the application. + - [ ] Remove all direct database queries and business logic. + - [ ] Replace them with calls to the appropriate service (e.g., `reporting_service.get_dashboard_metrics()`). + +- [ ] **3.3. Refactor SMM Logic:** + - [ ] Update the main dashboard route (`app/main/routes.py`). + - [ ] Modify the query for `new_clients_today` to use the new `Source.is_smm_source` flag instead of the hardcoded string search. + +## Phase 4: Testing & Verification + +- [ ] **4.1. Write Unit Tests:** + - [ ] Create comprehensive unit tests for `SalaryService`, ensuring all calculation modes are correct. + - [ ] Write unit tests for other critical service functions. + +- [ ] **4.2. Write Integration Tests:** + - [ ] Write tests to verify that key routes work as expected from request to response. + - [ ] Test that the `@permission_required` decorator correctly blocks unauthorized access. + - [ ] Test the full lifecycle of creating a transaction and verifying the reports. + +- [ ] **4.3. Manual Verification:** + - [ ] Run the application. + - [ ] Manually verify all the core workflows identified in the `DOMAIN_MAP.md`. + +## Phase 5: Finalization + +- [ ] **5.1. Code Cleanup:** + - [ ] Remove any dead code, old comments, and unused legacy files. + - [ ] Ensure all code is formatted according to a consistent style. + +- [ ] **5.2. Review Documentation:** + - [ ] Update the `README.md` if any setup or run instructions have changed. + - [ ] Ensure all analysis documents in `/agent` are up-to-date. diff --git a/agent/decisions/DECISIONS.md b/agent/decisions/DECISIONS.md new file mode 100644 index 0000000..5e0fe46 --- /dev/null +++ b/agent/decisions/DECISIONS.md @@ -0,0 +1,39 @@ +# Key Decisions + +This document provides detailed justification for the most critical decisions made in the `TRUTH_TABLE.md`. + +## 1. REWRITE: Master Salary Calculation Logic + +- **Decision:** The `Transaction.master_salary` property will be removed. All salary calculation logic will be moved into a new, dedicated `SalaryService`. +- **Reasoning:** + - **Incompleteness:** The existing property only calculates the percentage-based commission for a single transaction. It completely ignores the `fixed` and `mixed` salary modes, which require logic outside the model (e.g., aggregating daily work). This violates the Single Source of Truth principle. + - **Incorrect Placement:** Placing complex business logic inside a data model makes the model harder to understand, test, and maintain. It tightly couples the data representation to a specific business rule. + - **Proposed Solution:** A `SalaryService` will expose clear methods like `calculate_for_transaction(transaction)` and `calculate_for_period(master, start_date, end_date)`. This service will be the single, authoritative source for all salary-related computations, correctly handling all salary modes and edge cases. This makes the logic explicit, testable, and decoupled. + +## 2. REWRITE: Unify the Hybrid RBAC System + +- **Decision:** The legacy `User.role` string field will be completely removed. The application will exclusively use the `Role` and `Permission` database models for authorization. +- **Reasoning:** + - **Architectural Error:** Maintaining two parallel systems for authorization is a significant source of technical debt. It creates confusion (`which system is authoritative here?`), increases the chance of bugs (e.g., permissions getting out of sync), and makes the code harder to reason about. The property helpers (`is_admin`, `is_manager`) are a symptom of this problem, trying to bridge the two worlds. + - **Lack of Granularity:** The old string-based system is not granular. A user is an "admin" or they aren't. The `Permission`-based system allows for precise control, granting users only the specific rights they need to perform their duties (Principle of Least Privilege). + - **Proposed Solution:** + 1. A database migration script will be created to translate all existing `User.role` strings into assignments to the new `Role` objects. + 2. The `User.role` column will be dropped from the database schema. + 3. All code referencing the old role string (including the helper properties) will be refactored to use `user.has_permission('slug')`. + 4. A custom decorator, `@permission_required('slug')`, will be implemented to protect routes. + +## 3. REWRITE: Replace Hardcoded SMM Logic + +- **Decision:** The hardcoded `ilike('%инст%')` query in the main dashboard route will be removed. A new boolean field, `is_smm_source`, will be added to the `Source` model. +- **Reasoning:** + - **Brittle and Unmaintainable:** The current implementation is a classic example of a "magic string" workaround. It will break if the source is named "Instagram" instead of "инстаграм". It requires a code change to add a new SMM source like "Facebook". This is not scalable. + - **Business Logic in Presentation Layer:** This logic does not belong in a route. The determination of what constitutes an "SMM source" is a data-level concern. + - **Proposed Solution:** By adding an `is_smm_source` flag to the `Source` model, the logic becomes explicit and data-driven. A manager can simply tick a checkbox in the admin panel to mark a source as being SMM-related. The query then becomes a simple, efficient, and readable `Source.query.filter_by(is_smm_source=True)`. + +## 4. KEEP: Soft Deletes + +- **Decision:** The `SoftDeleteMixin` pattern will be kept and applied consistently across all relevant models. +- **Reasoning:** + - **Critical Business Requirement:** In a financial system of record, data should never be truly destroyed. Deleting a transaction could unbalance historical reports and break audit trails. Soft deletes provide the user experience of "deleting" while preserving data integrity. + - **Data Integrity:** It prevents the accidental deletion of parent records that might have cascading effects on child records, which could lead to orphaned data or database errors. + - **Implementation:** The mixin approach is clean and reusable, and should be the standard way of handling deletions for entities like `Transaction`, `Master`, `User`, `Expense`, etc.