diff --git a/ROADMAP.md b/ROADMAP.md index 5b9120a9..d5eb0a83 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -7,7 +7,20 @@ DocuElevate aims to be the premier open-source intelligent document processing platform, providing seamless integration with cloud storage providers, advanced AI-powered metadata extraction, and enterprise-grade security and scalability. -## Current Status (v0.5.0) +## Release Naming + +Each major milestone release carries a codename to anchor key project moments. These names appear in the status dashboard, build metadata, and changelog. For details, see [docs/ReleaseNaming.md](docs/ReleaseNaming.md). + +| Version Range | Codename | Theme | +|---------------|---------------|--------------------------------------------------| +| 0.5.x | **Foundation** | Core platform, multi-provider storage, AI, UI | +| 0.6.x | **Clarity** | Enhanced search, filtering, UI/UX improvements | +| 0.7.x | **Conductor** | Workflow automation, pipelines, rule-based logic | +| 1.0.x | **Summit** | Enterprise features, multi-tenancy, RBAC | +| 1.1.x | **Bridge** | Collaboration, sharing, analytics | +| 2.0.x | **Horizon** | On-premise AI, platform expansion | + +## Current Status (v0.5.0 "Foundation") ### Core Features ✅ - Multi-provider document storage (Dropbox, Google Drive, OneDrive, Nextcloud, S3, etc.) @@ -23,7 +36,7 @@ DocuElevate aims to be the premier open-source intelligent document processing p - Celery-based async task processing - OAuth2 authentication via Authentik with admin group support -## Short-term Goals (Q1-Q2 2026) - v0.4.x to v0.5.x +## Short-term Goals (Q1-Q2 2026) - v0.4.x to v0.5.x "Foundation" ### Quality & Stability 🎯 - **Test Coverage** (High Priority) @@ -53,7 +66,7 @@ DocuElevate aims to be the premier open-source intelligent document processing p - [x] Integrate Docker builds with releases ### Features - v0.4.0 -- **Enhanced Search & Filtering** +- **Enhanced Search & Filtering** → _preparing for v0.6.0 "Clarity"_ - [ ] Full-text search across documents - [ ] Advanced filtering by metadata, tags, date ranges - [ ] Saved search queries @@ -67,8 +80,8 @@ DocuElevate aims to be the premier open-source intelligent document processing p - [ ] Progress indicators for long-running tasks - [ ] Real-time notifications via WebSocket -### Features - v0.5.0 -- **Workflow Automation** +### Features - v0.5.0 "Foundation" +- **Workflow Automation** → _evolving into v0.7.0 "Conductor"_ - [ ] Custom processing pipelines - [ ] Conditional routing based on document type - [ ] Scheduled batch processing @@ -82,9 +95,9 @@ DocuElevate aims to be the premier open-source intelligent document processing p - [ ] Automatic duplicate detection - [ ] Intelligent document splitting -## Medium-term Goals (Q3-Q4 2026) - v1.0.x +## Medium-term Goals (Q3-Q4 2026) - v1.0.x "Summit" -### Enterprise Features - v1.0.0 +### Enterprise Features - v1.0.0 "Summit" - **Multi-tenancy** - [ ] Organization/team management - [ ] Role-based access control (RBAC) @@ -106,7 +119,7 @@ DocuElevate aims to be the premier open-source intelligent document processing p - [ ] Custom webhook receivers - [ ] GraphQL API -### Features - v1.1.0 +### Features - v1.1.0 "Bridge" - **Collaboration** - [ ] Document sharing with expiring links - [ ] Comments and annotations @@ -121,7 +134,7 @@ DocuElevate aims to be the premier open-source intelligent document processing p - [ ] Cost analysis per provider - [ ] Export reports (PDF, CSV, Excel) -## Long-term Goals (2027+) - v2.0+ +## Long-term Goals (2027+) - v2.0+ "Horizon" ### Strategic Initiatives - **On-Premise AI Models** diff --git a/app/config.py b/app/config.py index 8dce1995..c8e14f9e 100644 --- a/app/config.py +++ b/app/config.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +import json import os from typing import Any, List, Optional, Union @@ -599,5 +600,51 @@ class Settings(BaseSettings): # Return basic info if file not found return f"Version: {self.version}\nBuild Date: {self.build_date}\nGit SHA: {self.git_sha}" + @property + def release_name(self) -> str | None: + """Get the release codename for the current version from release_names.json. + + Looks up the current version's minor version prefix (e.g., '0.5' for '0.5.3') + in release_names.json to find the associated codename. Returns None if no + codename is defined for the current version. + + Returns: + The release codename string, or None if not found. + """ + version = self.version + if not version or version == "unknown": + return None + + release_names_file = os.path.join(os.path.dirname(os.path.dirname(__file__)), "release_names.json") + if not os.path.exists(release_names_file): + return None + + try: + with open(release_names_file, "r") as f: + data = json.load(f) + + releases = data.get("releases", {}) + + # Try exact version match first (e.g., "0.5.0") + if version in releases: + return releases[version].get("codename") + + # Try minor version prefix (e.g., "0.5" for "0.5.3") + parts = version.split(".") + if len(parts) >= 2: + minor_prefix = f"{parts[0]}.{parts[1]}" + if minor_prefix in releases: + return releases[minor_prefix].get("codename") + + # Try major version prefix (e.g., "1" for "1.0.0") + if len(parts) >= 1: + major_prefix = parts[0] + if major_prefix in releases: + return releases[major_prefix].get("codename") + + return None + except (json.JSONDecodeError, KeyError, IndexError): + return None + settings = Settings() diff --git a/app/views/base.py b/app/views/base.py index 8b10c514..941c16ed 100644 --- a/app/views/base.py +++ b/app/views/base.py @@ -30,6 +30,7 @@ def template_response_with_version(*args, **kwargs): # If context dict is provided, add version to it if len(args) >= 2 and isinstance(args[1], dict): args[1].setdefault("version", settings.version) + args[1].setdefault("release_name", getattr(settings, "release_name", None)) # Inject CSRF token from request state when available req = args[1].get("request") if req is not None and hasattr(req.state, "csrf_token"): @@ -38,6 +39,7 @@ def template_response_with_version(*args, **kwargs): args[1].setdefault("ui_default_color_scheme", getattr(settings, "ui_default_color_scheme", "system")) elif "context" in kwargs and isinstance(kwargs["context"], dict): kwargs["context"].setdefault("version", settings.version) + kwargs["context"].setdefault("release_name", getattr(settings, "release_name", None)) req = kwargs["context"].get("request") if req is not None and hasattr(req.state, "csrf_token"): kwargs["context"].setdefault("csrf_token", req.state.csrf_token) diff --git a/app/views/status.py b/app/views/status.py index 8c44c993..585a9df4 100644 --- a/app/views/status.py +++ b/app/views/status.py @@ -73,12 +73,16 @@ async def status_dashboard(request: Request): # Get notification URLs for the notification box notification_urls = getattr(settings, "notification_urls", []) + # Get release codename if available + release_name = getattr(settings, "release_name", None) + return templates.TemplateResponse( "status_dashboard.html", { "request": request, "providers": providers, "app_version": settings.version, + "release_name": release_name, "build_date": build_date, "debug_enabled": getattr(settings, "debug", False), "last_check": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), diff --git a/docs/ReleaseNaming.md b/docs/ReleaseNaming.md new file mode 100644 index 00000000..348aa010 --- /dev/null +++ b/docs/ReleaseNaming.md @@ -0,0 +1,127 @@ +# Release Naming Guide + +DocuElevate uses **automated semantic versioning** via [python-semantic-release](https://github.com/python-semantic-release/python-semantic-release) combined with **named release anchors** (codenames) for milestone releases. This guide explains how the two systems work together. + +## How It Works + +### Automated Versioning (Patch & Minor Releases) + +Every merge to `main` is analyzed by `python-semantic-release`: + +- **`feat:` commits** → minor version bump (e.g., 0.5.0 → 0.6.0) +- **`fix:` / `perf:` commits** → patch version bump (e.g., 0.5.0 → 0.5.1) +- **`docs:` / `chore:` / etc.** → no version bump + +This happens automatically — no manual intervention needed. + +### Named Release Anchors (Codenames) + +Major milestone releases carry a **codename** that anchors the release in project history. Codenames: + +- Are defined in [`release_names.json`](../release_names.json) at the project root +- Map to **minor version ranges** (e.g., all `0.5.x` releases share the codename "Foundation") +- Appear in the status dashboard, build metadata, and footer +- Do **not** interfere with automatic version numbering + +### Current Release Names + +| Version Range | Codename | Description | +|---------------|----------------|----------------------------------------------------------| +| 0.5.x | **Foundation** | Core platform with multi-provider storage, AI, and UI | +| 0.6.x | **Clarity** | Enhanced search, filtering, and improved UI/UX | +| 0.7.x | **Conductor** | Workflow automation, custom pipelines, rule-based logic | +| 1.0.x | **Summit** | Enterprise-ready: multi-tenancy, RBAC, horizontal scaling| +| 1.1.x | **Bridge** | Collaboration features, document sharing, analytics | +| 2.0.x | **Horizon** | On-premise AI, advanced management, platform expansion | + +## Adding a New Release Name + +1. **Edit `release_names.json`** at the project root: + +```json +{ + "releases": { + "0.8": { + "codename": "YourCodename", + "description": "Short description of what this release series focuses on", + "milestone": "v0.8.0 - Your Milestone Name" + } + } +} +``` + +2. **Update `ROADMAP.md`** to include the codename in the appropriate milestone section. + +3. **Update this documentation** to add the new entry to the table above. + +The codename will automatically appear in: +- The application footer (all pages) +- The status dashboard (`/status`) +- Build metadata (`RUNTIME_INFO` file) + +## How the Lookup Works + +The application resolves codenames using a cascading lookup against the current version: + +1. **Exact match**: Checks if the full version (e.g., `0.5.3`) has an entry +2. **Minor prefix**: Checks the minor version prefix (e.g., `0.5`) +3. **Major prefix**: Checks the major version prefix (e.g., `0`) + +This means all patch releases within a minor version series inherit the same codename. + +## Codename Naming Conventions + +When choosing codenames, follow these guidelines: + +- **Use single, evocative words** that relate to the release's theme +- **Keep names professional** — they appear in user-facing UI +- **Pick names that hint at the milestone's focus** (e.g., "Foundation" for core platform, "Conductor" for workflow automation) +- **Avoid names that could become dated** or reference external products +- **Ensure uniqueness** — no two releases should share a codename + +## Integration with Milestones + +Each codename maps to a GitHub milestone. The `milestone` field in `release_names.json` matches the milestone title used for issue tracking: + +``` +v0.7.0 - Workflow Automation → codename: "Conductor" +v1.0.0 - Enterprise → codename: "Summit" +``` + +This creates a clear link between planning (milestones), delivery (releases), and communication (codenames). + +## Best Practices: Blending Automated and Named Releases + +### Do + +- ✅ Let semantic-release handle all version numbering automatically +- ✅ Use codenames for **milestone releases** (minor/major versions), not every patch +- ✅ Reference codenames in release notes and changelogs for major versions +- ✅ Keep `release_names.json` in sync with `ROADMAP.md` +- ✅ Announce codenames in GitHub Release descriptions for milestone versions + +### Don't + +- ❌ Manually edit the `VERSION` file — it's managed by semantic-release +- ❌ Create codenames for every patch release (0.5.1, 0.5.2, etc.) +- ❌ Use codenames that conflict with version numbers +- ❌ Skip updating `release_names.json` when adding a new milestone to the roadmap + +## Where Codenames Appear + +| Location | Format | +|-------------------------|-----------------------------------------| +| Status dashboard | `App Version: 0.5.3 "Foundation"` | +| Page footer | `Version 0.5.3 "Foundation"` | +| RUNTIME_INFO metadata | `Release Name: Foundation` | +| ROADMAP.md | Section headers include codenames | + +## File Reference + +| File | Purpose | +|---------------------------|--------------------------------------------| +| `release_names.json` | Source of truth for version-to-codename map| +| `app/config.py` | `release_name` property reads the JSON | +| `scripts/generate_build_metadata.sh` | Includes codename in RUNTIME_INFO | +| `app/views/base.py` | Injects `release_name` into all templates | +| `ROADMAP.md` | Displays codenames alongside milestones | diff --git a/frontend/templates/base.html b/frontend/templates/base.html index c0555bc5..b5573358 100644 --- a/frontend/templates/base.html +++ b/frontend/templates/base.html @@ -230,7 +230,7 @@ License - Attributions - - Version {{ app_version|default(version, true) }} + Version {{ app_version|default(version, true) }}{% if release_name %} "{{ release_name }}"{% endif %} diff --git a/frontend/templates/status_dashboard.html b/frontend/templates/status_dashboard.html index bd4a0bbc..c6e57e40 100644 --- a/frontend/templates/status_dashboard.html +++ b/frontend/templates/status_dashboard.html @@ -13,7 +13,7 @@ This dashboard shows the status of all configured integrations and targets.