diff --git a/README.md b/README.md index eeb9bfb..bcbc759 100644 --- a/README.md +++ b/README.md @@ -1,179 +1,320 @@ -# πΏ Nature In Pots β Ultra Plant Tracker Platform +# Nature In Pots Community Site -> Modular, collaborative, end-to-end plant tracking and pricing platform with QR+barcode IDs, propagation logs, resale tools, and role-based management. +    + +A modular, plugin-driven platform for tracking plants, propagation lineage, growth logs, pricing, and community submissionsβbuilt with Flask, MySQL, and Neo4j. --- -## π§© Overview +## π Table of Contents -This is a full-feature, plugin-driven Flask 2+ web application for managing and tracking plant ownership, propagation, pricing, and growth. It supports dynamic plant attributes, collaboration groups, trade logs, QR/barcode labeling, resale workflows, offline sync, moderator tools, and future AI/ML modules. +1. [Introduction & Goals](#introduction--goals) +2. [Architecture & Tech Stack](#architecture--tech-stack) +3. [Quickstart & Installation](#quickstart--installation) +4. [Project Structure](#project-structure) +5. [Core Features](#core-features) -Built for hobbyists, businesses, breeders, and community gardens. + 1. [Plant Profiles](#plant-profiles) + 2. [Grow Logs](#grow-logs) + 3. [Verified Lineage Tracking](#verified-lineage-tracking) + 4. [Pricing Logic](#pricing-logic) + 5. [Substrate & Fertilizer Tracking](#substrate--fertilizer-tracking) + 6. [Shipping Tracker](#shipping-tracker) + 7. [Plant Folders](#plant-folders) + 8. [Media Gallery & Voting](#media-gallery--voting) + 9. [QR & Barcode Labeling](#qr--barcode-labeling) + 10. [Offline Sync (PWA)](#offline-sync-pwa) + 11. [Smart Tools](#smart-tools) +6. [Plugin Ecosystem](#plugin-ecosystem) +7. [Data Models & Schema](#data-models--schema) +8. [APIs & CLI](#apis--cli) +9. [User Interface & PWA](#user-interface--pwa) +10. [Security & Privacy](#security--privacy) +11. [Permissions Matrix](#permissions-matrix) +12. [Admin & Dev Tools](#admin--dev-tools) +13. [Internationalization](#internationalization) +14. [Roadmap & Future Enhancements](#roadmap--future-enhancements) +15. [Contributing](#contributing) +16. [License](#license) --- -## π Core Features +## π Introduction & Goals + +Nature In Pots empowers hobbyists, breeders, and businesses to: + +* **Create & manage** rich plant profiles (names, lineage, pricing, notes). +* **Track growth** via logs with metrics, health/pest events, and custom traits. +* **Visualize propagation** on a Neo4j-powered ancestry graph. +* **Upload & curate** imagesβcommunity-voted, featured selections. +* **Handle secure transfers** of ownership, preserving full history and privacy. +* **Organize** plants into folders with shareable QR/back-barcodes. +* **Import & export** comprehensive CSV/ZIP bundles, including media. +* **Extend** via plugins: materials, ledger, inventory, vendor collectives, and more. + +--- + +## π Architecture & Tech Stack + +* **Backend**: Python 3.11, Flask 2+, Flask-Login, Flask-Migrate (Alembic) +* **ORM**: SQLAlchemy (MySQL) & Neo4j Bolt driver +* **Storage**: Local FS (`UPLOAD_FOLDER`), optional S3 sync +* **Frontend**: Bootstrap 5, responsive + PWA caching +* **QR/Barcode**: Pillow + qrcode, CODE-128 barcodes +* **Security**: End-to-End encryption with optional key escrow +* **Testing**: pytest + coverage; CI/CD via GitHub Actions +* **Containerization**: Docker & Docker Compose + +--- + +## π Quickstart & Installation + +1. **Clone** + + ```bash + git clone https://github.com/yourorg/nip-community.git + cd nip-community + ``` +2. **Virtualenv & Dependencies** + + ```bash + python3 -m venv venv; source venv/bin/activate + pip install -r requirements.txt + ``` +3. **Env & Config** + Copy `.env.example` β `.env`, set `FLASK_APP=app`, DB/Neo4j URLs, `SECRET_KEY`, `UPLOAD_FOLDER`. +4. **Migrations** + + ```bash + flask db init + flask db migrate + flask db upgrade + ``` +5. **Run** + + ```bash + flask run --reload + ``` + + Access [http://localhost:5000](http://localhost:5000) + +--- + +## π Project Structure + +``` +. +βββ app/ # Core app factory, auth, errors, Neo4j utils +βββ plugins/ # Feature modules (plant, media, utility, etc.) +β βββ plant/ +β βββ media/ +β βββ utility/ +β βββ growlog/ +β βββ submissions/ +β βββ vendor/ +β βββ (future: materials, ledger, inventory, collective) +βββ migrations/ # Alembic scripts +βββ static/ # Global assets +βββ templates/ # Shared base templates +βββ tests/ # pytest suite +βββ Dockerfile +βββ docker-compose.yml +βββ requirements.txt +βββ README.md # β this file +``` + +--- + +## β Core Features ### π± Plant Profiles -- Add, edit, and log plants with full propagation and ownership history -- Each plant is assigned a permanent, scannable **QR code** and **barcode** -- Plants can be marked as `Public`, `Unlisted`, or `Folder-only` -- All pricing, logs, and lineage are tied to a plant ID and user -### π§Ύ Grow Logs -- Add logs with images, notes, and growth metrics -- Track success/failure events, mutation events, pest/disease sightings -- Link logs to substrate recipes and fertilizers +* **Create/Edit** plants with: + + * UUID & custom slug + * Plant type (seed, cutting, tissue culture, division, etc.) + * Common & scientific names (with lookup/autocomplete) + * Vendor, notes, active flag + * Parent (`mother_uuid`) references +* **Detail page** shows metadata, lineage nav, QR links, folders. + +### π Grow Logs + +* Timestamped logs with: + + * Size, leaf count, substrate mix, potting notes + * Health/pest/disease events & treatments + * Up to 5 images per log +* **Timeline** view on plant detail. ### π Verified Lineage Tracking -- Lineage links are created by the new owner -- Parent plant's owner must **approve** the linkage -- Verified lineage is marked with a badge and shown in plant lineage tree -- Pending links are visible only to the creator + +* **Neo4j** graph for parentβchild relationships. +* Pending link requests: parent-owner approval required. +* Verified links get a badge; unverified shown in draft. ### π° Pricing Logic -- Only the current owner and admins can see pricing -- On transfer, original price is retained but hidden from the buyer -- Buyer must submit their own price for tracking resale data -- Admins see full price history; mods and others do not -### π§ͺ Substrate + Fertilizer Tracking -- Track custom mixes by ingredient (e.g., βFine Pumiceβ, βLarge Barkβ) -- Store cost per ingredient and auto-calculate total mix cost -- Recipes can be reused across plants -- Fertilizer schedules can be attached to logs and outcomes tracked +* **Owner & admin** see full pricing history; others do not. +* On transfer, sellerβs last price is retained but hidden; buyer sets new price. +* **Price records** tracked as `PriceHistory` entries. +* Visibility toggles: `public`, `unlisted`, `folder-only`. + +### π§ͺ Substrate & Fertilizer Tracking + +* Define **mix recipes**: ingredient list with cost per unit. +* Auto-calculate total mix cost based on usage (e.g., ounces, cups). +* Reusable recipes attachable to grow logs. +* **Fertilizer schedules** logged and outcomes tracked. ### π¦ Shipping Tracker -- When a plant is sold, sellers can add: - - Carrier, tracking number, est. delivery date -- Ownership updates post buyer confirmation -- Shipping logs are attached to the plant transfer log + +* During sale, seller enters: carrier, tracking number, est. delivery. +* Transfer completes after buyer confirmation. +* Shipping events attached to ownership log. ### π Plant Folders -- Organize plants into folders (e.g., βFor Saleβ, β2025 Spring Batchβ) -- Each folder gets its own QR code: + +* Organize plants into **named folders** (e.g., βFor Saleβ, β2025 Seedlingsβ). +* Each folder has its own QR code and slug: `https://domain.com/{username}/folder/{id}|{slug}` -- Folders can be public, private, or unlisted +* Folder visibility: `public`, `private`, `unlisted`. + +### πΌ Media Gallery & Voting + +* **Upload**, rotate, delete images per plant/growlog. +* Per-user βheartβ or βbroken heartβ voting. +* **Featured image** toggle via media plugin; batch fallback to top-voted. +* EXIF data stripped on upload. + +### π QR & Barcode Labeling + +* **QR codes** (SVG & PNG) unique per plant/folder. +* **Barcode (CODE-128)** fallback; splits long data into stacked barcodes. +* Printable labels via dashboard. + +### πΆ Offline Sync (PWA) + +* Full form support offline (plants, logs, submissions). +* Sync queue when back online. +* QR/barcode generation deferred until server sync. + +### π€ Smart Tools + +* **Reputation System**: users rated by buyers (accuracy, responsiveness). +* βTrusted Growerβ badge auto-granted. +* **Inter-Plant Comparison**: side-by-side charts of growth metrics or events. --- -## π§ββοΈ Users, Roles, and Groups +## π Plugin Ecosystem -### π€ User Roles -- **User** β default -- **Moderator** β can manage flags, notes -- **Admin** β full backend, plugin, pricing, banning control -- Roles are extensible via admin UI - -### π‘ Moderator Panel -- View and resolve reports -- Add private notes to users or plants (e.g., warnings, suspicion) -- Ban users - - Banned users' plants become read-only - - Cannot add new plants - - Buyers can request transfer via email approval from banned seller - -### π₯ Collaboration Groups -- Users can form groups to share: - - Logs - - Images - - Pricing (opt-in) -- Groups have role-based permissions (manager, editor, viewer) -- Useful for stores, teams, or shared collections +| Plugin | Purpose | Status | +| --------------- | --------------------------------------------- | ---------- | +| **plant** | Core plant CRUD & lineage | β Live | +| **media** | Image storage, EXIF, voting, featured | β Live | +| **utility** | Import/Export CSV/ZIP, QR code generation | β Live | +| **growlog** | Growth logs & update images | β Live | +| **submissions** | Community submissions & voting | β Live | +| **vendor** | Vendor/collective profiles, membership, roles | β Live | +| **materials** | Potting mixes, proprietary flags | π Planned | +| **ledger** | Cost logs, fees, tax, shipping | π Planned | +| **inventory** | Stock management, restock/depletion | π Planned | +| **collective** | Shared groups with RBAC | π Planned | --- -## π·οΈ Labeling System: QR + Barcode +## π Data Models & Schema -### QR Code -- Generated on server after initial sync -- Unique to plant, never changes -- SVG and PNG available +Refer to `/migrations/` for full schema. Key tables include: -### Barcode Fallback -- CODE-128 format -- If data too long, split into stacked barcodes -- Same encoded info: plant ID, owner ID, visibility, timestamp -- Printable as label from dashboard +* `users`, `roles`, `user_roles` +* `plant_common_name`, `plant_scientific_name` +* **`plant`**: FKs β common, scientific, owner, mother\_uuid, featured\_media +* `media`: FKs β plant\_id, growlog\_id, uploader +* `featured_image` +* `plant_update`, `update_image` +* `plant_ownership_log`, `transfer_request` +* `submission`, `submission_image` +* `health_event`, `trait`, lookup tables +* `vendor_profile`, `vendor_member`, `affiliation_request`, `claim_request` +* `listing`, `price_history` +* `inventory_item`, `restock_event`, `depletion_event` --- -## π Permissions Matrix +## π APIs & CLI -| Feature | Owner | Group Member | Moderator | Admin | -|--------------------------|-------|---------------|-----------|--------| -| View Logs | β | β (if shared) | β | β | -| Edit Logs | β | π* | π« | β | -| View Pricing | β | β (opt-in) | π« | β | -| Ban User / Flag Review | π« | π« | β | β | -| Approve Lineage | π« | π« | π« | β | -| Confirm Lineage | β | π« | π« | β | +* **REST**: `/api/v1/` CRUD, OpenAPI docs, JWT auth, rate limiting +* **GraphQL**: `/graphql` batched queries for plants + relations +* **CLI**: -π* if granted by group manager + * `flask db {init,migrate,upgrade}` + * `flask user create` + * `flask plugin {install,list,enable}` + * `flask preload-data` --- -## π Offline Sync (PWA) -- Full add/log/edit possible offline -- Sync queue uploads on connection -- QR/barcodes generated **after** server confirms sync -- Client-side validation before queue +## π User Interface & PWA + +* **Bootstrap 5** responsive layouts +* **Desktop**: large gallery + thumbnail carousel +* **Mobile**: grid lightbox with pinch-zoom & close button +* Offline caching via service worker --- -## π§ Smart Tools +## π Security & Privacy -### βοΈ User Reputation System -- Users rated after trades (accuracy, responsiveness, helpfulness) -- βTrusted Growerβ tag auto-assigned above threshold -- Can be revoked via vote or admin action - -### πΏ Inter-Plant Comparison -- Timeline comparison for growth, size, or log outcomes -- Side-by-side charts and event overlays +* **End-to-End Encryption** for notes, logs, pricing +* **Key Escrow** (opt-in) vs **Maximum Privacy** (no escrow) +* **Blind Transfers**: admin can reassign without decryption +* **Audit Logs**: immutable record of all actions +* **Role-Based Access**: owner, group member, moderator, admin --- -## π§ Admin & Dev Tools +## π Permissions Matrix -### π€ Seed Data Generator -- Seeds with common aroids, herbs, and test users -- Covers full range of roles, plant types, and edge cases +| Action | Owner | Group | Mod | Admin | +| ----------------------------- | :---: | :---: | :-: | :---: | +| Create/Edit own plants & logs | β | β \* | β | β | +| View public plants/logs | β | β | β | β | +| Approve lineage & submissions | β | β | β | β | +| Manage vendors/collectives | β | β | β | β | +| Transfer override (no-owner) | β | β | β | β | +| Plugin management & settings | β | β | β | β | -### π Plugin System -- CLI & plugin discovery system -- Admin can toggle plugins -- Plugin types: CLI, UI Panel, API extension, webhook, scheduler - -### π Data Export / Disaster Recovery -- Export: SQL dump, file archive, JSON profile -- Restore: Admin-initiated rollback or full upload restore +\* if granted by group manager --- -## π£ API System +## β Admin & Dev Tools -### REST & GraphQL APIs -- REST: OpenAPI-documented endpoints -- GraphQL: Advanced multi-entity queries -- JWT-secured -- Follows role-based access rules +* **Moderator Panel**: flag review, user notes, bans +* **Seed Data Generator**: sample users, plants, logs +* **Plugin CLI**: install/enable/disable plugins at runtime +* **ERD Viewer**: visualize database schema +* **Disaster Recovery**: SQL dump + file archive + JSON profiles --- -## π Internationalization -- Flask-Babel integration -- Language switcher in UI -- Community-managed translation interface (admin toggled) +## π Internationalization + +* **Flask-Babel** for translations +* Language switcher in UI +* Community-managed translation portal (admin toggle) --- -## π Future Enhancements +## π£ Roadmap & Future Enhancements -- π§ AI Journal Assistant (log suggestions, summarization) -- π Calendar View for logs/reminders -- π§° Visual ERD Generator Tool -- π Live Auctions Plugin (for curated resale events) +* AI-powered journal assistant & mutation detection +* Calendar reminders for watering, fertilizing +* Visual ERD generator tool in admin UI +* Live auction & escrow plugin +* Third-party webhook integrations (Zapier, Discord) --- diff --git a/Security.md b/Security.md new file mode 100644 index 0000000..0f338b2 --- /dev/null +++ b/Security.md @@ -0,0 +1,151 @@ +# π SECURITY.md +_Nature In Pots Community β Data & Platform Security Policy_ + +--- + +## π Overview + +This document outlines the security practices, encryption policies, and recovery procedures used by the **Nature In Pots Community** platform. Our goal is to maintain the privacy and integrity of user data while offering secure collaboration, recovery, and administrative tooling where appropriate. + +--- + +## β Security Principles + +We follow a simple core policy: + +> **Your data is yours.** You choose who sees it, how it's stored, and what happens to it. + +To support this, we implement: + +- **End-to-End Encryption (E2EE)** for sensitive records. +- **User-controlled privacy flags** and public visibility toggles. +- **Role-based access control** for owners, groups, vendors, and admins. +- **Optional key escrow** to allow secure, auditable recovery when necessary. +- **Strict audit trails** for all user and admin actions. +- **Granular ownership transfers** that preserve privacy unless explicitly permitted. + +--- + +## π§βπΎ User Data Encryption + +When a user creates or imports plants, grow logs, health reports, media, or related records, the following options apply for encryption and recovery: + +### π Option 1: Maximum Privacy Mode (No Escrow) + +- Data is encrypted with a user-owned key never shared with the server. +- Only the user can decrypt or transfer ownership. +- If the key is lost, **data is unrecoverable**. Even admins cannot assist. + +### ποΈ Option 2: Recovery-Enabled Mode (Escrow) + +- A securely wrapped recovery key is stored using *key escrow*. +- Admins may **transfer ownership** of encrypted records to a new user (e.g., due to account inactivity or verified reassignment), but cannot read or decrypt the data. +- All access and recovery actions are **audited** and must be explicitly justified. + +Users are prompted to choose between these options on signup and may change their preference at any time from **Account Settings β Privacy Options**. + +#### TL;DR (Explain Like Iβm 5) + +- **Full Privacy Mode**: Only you have the key to your secret garden. Lose it = locked out forever. +- **Recovery Mode (Default)**: Still private, but we keep a spare key in a vault. We can give your garden to a new gardener if needed, but we still canβt peek inside. + +--- + +## π§βπ€βπ§ Groups, Vendors, and Collectives + +A "collective identity" (e.g., vendor, grow group, brand) may be created and owned by one or more users. + +- Each collective has its own permission rules. +- Permissions include: `read`, `edit`, `propose changes`, `submit grow logs`, `mark as sold`, and `manage members`. +- Collective-owned content inherits the encryption mode of the creator or the designated owner. + +All actions taken under a collective identity are tagged with the acting user and timestamped. + +--- + +## π Ownership & Record Transfers + +Records (plants, logs, vendors, mixes, etc.) can be transferred between: + +- Individuals β Individuals +- Individuals β Vendors / Groups +- Vendors β Vendors + +**Transfer rules:** + +| Encryption Mode | Owner Action Required | Admin Recovery Allowed | +|------------------|------------------------|-------------------------| +| No Escrow | β Yes | β No | +| Escrow Enabled | π« Optional (if owner inactive) | β Yes | + +All transfers are logged with before/after states and include initiator ID, reason, and timestamp. + +--- + +## πͺ΅ Audit Logging + +All significant actions are audit-logged: + +- Logins, failed logins, and 2FA attempts +- Data modifications (create, edit, delete) +- Media uploads +- Grow log entries +- Transfers and permission changes +- Escrow-based recoveries + +Logs are not publicly accessible but may be disclosed to the user on request or subpoena. + +--- + +## β οΈ Admin Privileges & Limitations + +Admins can: + +- Approve or remove public content +- Recover records **only** under escrow-enabled mode +- View metadata (timestamps, image hashes, plant IDs) +- **Not** decrypt user content in maximum privacy mode +- **Not** alter audit trails or impersonate users + +--- + +## π§ͺ Developer Guidelines + +### Secret Management + +- All crypto secrets must be kept in `.env` or secure vaults. +- Never commit user-generated keys or tokens to Git. + +### Input Sanitization + +- All user inputs are escaped before rendering. +- Media uploads are validated and stripped of EXIF/GPS metadata. + +### TLS & HTTPS + +- All public and private routes must use HTTPS. +- Local dev servers use self-signed certs or SSL proxy. + +--- + +## π‘οΈ Future Features (Planned) + +- β Invite-only registration support +- β Per-record expiration and auto-archival +- π Self-destructing records (for sensitive notes) +- 𧬠Cryptographic signatures on propagation history +- π§Ύ Printable audit exports per plant/vendor + +--- + +## π Contact & Reporting Security Issues + +If you find a vulnerability or need to report a breach: + +- Email: [security@natureinpots.com](mailto:security@natureinpots.com) +- PGP Key: Coming soon +- Please include reproduction steps and affected data + +--- + +_This document is maintained by the Nature In Pots security team. Last updated: {{ current_year }}._ diff --git a/app/errors.py b/app/errors.py index 177089e..06d4677 100644 --- a/app/errors.py +++ b/app/errors.py @@ -4,7 +4,7 @@ bp = Blueprint('errors', __name__) @bp.app_errorhandler(400) def bad_request(error): - return render_template('400.html'), 400 + return render_template('400.html', error=error), 400 @bp.app_errorhandler(404) def bad_request(error): diff --git a/entrypoint.sh b/entrypoint.sh index a1878fb..82f0f2b 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -24,9 +24,7 @@ fi # Autogenerate new migration if needed echo "[π οΈ] Checking for new schema changes" -if ! flask db migrate -m "auto-migrate" --compare-type --render-as-batch; then - echo "[βΉοΈ] No schema changes detected" -fi +flask db migrate -m "auto-migrate" || echo "[βΉοΈ] No schema changes detected" # Apply migrations echo "[βΆοΈ] Applying database migrations" diff --git a/migrations/env.py b/migrations/env.py index f47ac5c..12671da 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -53,7 +53,7 @@ def run_migrations_online(): target_metadata=target_metadata, compare_type=True, sort_tables=True, - render_as_batch=True, # β important! + render_as_batch=True, ) with context.begin_transaction(): context.run_migrations() diff --git a/migrations/versions/209596f02c2a_auto_migrate.py b/migrations/versions/209596f02c2a_auto_migrate.py new file mode 100644 index 0000000..eca65e2 --- /dev/null +++ b/migrations/versions/209596f02c2a_auto_migrate.py @@ -0,0 +1,28 @@ +"""auto-migrate + +Revision ID: 209596f02c2a +Revises: 42ce181f4eab +Create Date: 2025-06-27 09:50:03.962692 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '209596f02c2a' +down_revision = '42ce181f4eab' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/migrations/versions/42ce181f4eab_auto_migrate.py b/migrations/versions/42ce181f4eab_auto_migrate.py new file mode 100644 index 0000000..d043d9c --- /dev/null +++ b/migrations/versions/42ce181f4eab_auto_migrate.py @@ -0,0 +1,28 @@ +"""auto-migrate + +Revision ID: 42ce181f4eab +Revises: 93f8a5cbc643 +Create Date: 2025-06-27 09:47:28.698481 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '42ce181f4eab' +down_revision = '93f8a5cbc643' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/migrations/versions/93f8a5cbc643_auto_migrate.py b/migrations/versions/93f8a5cbc643_auto_migrate.py new file mode 100644 index 0000000..4ba265e --- /dev/null +++ b/migrations/versions/93f8a5cbc643_auto_migrate.py @@ -0,0 +1,28 @@ +"""auto-migrate + +Revision ID: 93f8a5cbc643 +Revises: 9cc2626a6e79 +Create Date: 2025-06-27 09:31:27.528072 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '93f8a5cbc643' +down_revision = '9cc2626a6e79' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/migrations/versions/9cc2626a6e79_auto_migrate.py b/migrations/versions/9cc2626a6e79_auto_migrate.py new file mode 100644 index 0000000..b456be3 --- /dev/null +++ b/migrations/versions/9cc2626a6e79_auto_migrate.py @@ -0,0 +1,28 @@ +"""auto-migrate + +Revision ID: 9cc2626a6e79 +Revises: d54a88422a68 +Create Date: 2025-06-27 09:28:40.656166 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '9cc2626a6e79' +down_revision = 'd54a88422a68' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/migrations/versions/d54a88422a68_auto_migrate.py b/migrations/versions/d54a88422a68_auto_migrate.py new file mode 100644 index 0000000..fb6ac3f --- /dev/null +++ b/migrations/versions/d54a88422a68_auto_migrate.py @@ -0,0 +1,28 @@ +"""auto-migrate + +Revision ID: d54a88422a68 +Revises: d7bbffbbc931 +Create Date: 2025-06-27 09:24:27.947480 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'd54a88422a68' +down_revision = 'd7bbffbbc931' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/migrations/versions/d7bbffbbc931_auto_migrate.py b/migrations/versions/d7bbffbbc931_auto_migrate.py new file mode 100644 index 0000000..ead1201 --- /dev/null +++ b/migrations/versions/d7bbffbbc931_auto_migrate.py @@ -0,0 +1,32 @@ +"""auto-migrate + +Revision ID: d7bbffbbc931 +Revises: +Create Date: 2025-06-27 09:20:35.600333 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'd7bbffbbc931' +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('grow_logs', schema=None) as batch_op: + batch_op.add_column(sa.Column('event_type', sa.String(length=50), nullable=False)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('grow_logs', schema=None) as batch_op: + batch_op.drop_column('event_type') + + # ### end Alembic commands ### diff --git a/migrations/versions/f00a9585a348_auto_migrate.py b/migrations/versions/f00a9585a348_auto_migrate.py new file mode 100644 index 0000000..5fd857f --- /dev/null +++ b/migrations/versions/f00a9585a348_auto_migrate.py @@ -0,0 +1,28 @@ +"""auto-migrate + +Revision ID: f00a9585a348 +Revises: 209596f02c2a +Create Date: 2025-06-27 09:55:08.249023 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'f00a9585a348' +down_revision = '209596f02c2a' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/nip.zip b/nip.zip index 44a807a..54feb40 100644 Binary files a/nip.zip and b/nip.zip differ diff --git a/plugins/core_ui/templates/core_ui/base.html b/plugins/core_ui/templates/core_ui/base.html index f4b691f..29d4fec 100644 --- a/plugins/core_ui/templates/core_ui/base.html +++ b/plugins/core_ui/templates/core_ui/base.html @@ -1,100 +1,218 @@
- - - -