2 Commits
v0.1.8 ... main

14 changed files with 329 additions and 112 deletions

View File

@@ -1,16 +1,18 @@
# GovOPlaN Issue Reporting Codex Guide
# GovOPlaN Tickets Codex Guide
## Scope
This repository owns the GovOPlaN Issue Reporting platform module seed.
This repository owns the GovOPlaN Tickets domain module seed.
Public or internal problem reporting for broken infrastructure, damaged rooms, IT outages, safety issues, accessibility issues, triage, and routing.
Tickets are queue-oriented reports, requests, incidents, problems, and service
work. Formal administrative procedures remain owned by `govoplan-cases`.
## Boundaries
- Depend on kernel contracts from `govoplan-core` and access contracts from `govoplan-access`.
- Keep domain behavior in this module; expose integration through manifests, capabilities, API routes, events, typed DTOs, and documentation topics.
- Do not import internals from sibling feature modules. Use optional dependencies and capabilities for cross-module behavior.
- Escalation to a case creates a stable cross-module reference; never mutate a ticket into a case or copy a case's authoritative procedural state.
- Keep the seed non-invasive until runtime routes, persistence, and WebUI flows are intentionally designed.
## Local Workflow

View File

@@ -1,43 +1,56 @@
# GovOPlaN Issue Reporting
# GovOPlaN Tickets
<!-- govoplan-repository-type:start -->
**Repository type:** module (domain).
<!-- govoplan-repository-type:end -->
`govoplan-issue-reporting` is the GovOPlaN platform module seed for public or internal problem reporting for broken infrastructure, damaged rooms, IT outages, safety issues, accessibility issues, triage, and routing.
`govoplan-tickets` is the generic GovOPlaN work-intake and service-ticket
module. It covers public and internal reports, requests, incidents, problems,
queues, triage, routing, assignment, service-level state, and auditable
resolution.
Its runtime module ID is `tickets`.
This repository is initialized as a discoverable module seed. It exposes a module manifest, initial permissions, role templates, documentation metadata, Gitea workflow templates, and a focused manifest test. It intentionally does not yet add HTTP routes, database models, migrations, or WebUI navigation.
## Initial Ownership
- issue intake
- problem category taxonomy
- triage and routing facts
- public reporter references
- handoff targets
- ticket identity, type, priority, state, and queue
- public and internal intake profiles
- reporter/requester and affected-object references
- triage, routing, assignment, and service-level facts
- resolution evidence and escalation links
## Boundaries
This module does not own:
Tickets are operational work items. They may be resolved entirely within a
queue or linked to a task, project, asset, facility, or formal case.
- internal service desk execution
- legal case handling
- asset lifecycle management
Cases are different: `govoplan-cases` owns the authoritative procedural record
for an administrative matter, including parties, evidence, decisions,
procedural deadlines, and retention. Escalating a ticket creates a stable link;
it does not rewrite the ticket as a case.
Detailed boundary notes are in [docs/ISSUE_REPORTING_DOMAIN_BOUNDARY.md](docs/ISSUE_REPORTING_DOMAIN_BOUNDARY.md).
Detailed boundary notes are in
[docs/TICKETS_DOMAIN_BOUNDARY.md](docs/TICKETS_DOMAIN_BOUNDARY.md).
## Integrations
Expected optional integrations:
- helpdesk
- cases
- projects
- wiki
- assets
- facilities
- forms-runtime
- forms_runtime
- portal
- files
- workflow
- tasks
- mail
- notifications
- search
## Development Install
@@ -45,23 +58,24 @@ From the core checkout:
```bash
cd /mnt/DATA/git/govoplan-core
./.venv/bin/python -m pip install -e ../govoplan-issue-reporting
./.venv/bin/python -m pip install -e ../govoplan-tickets
```
Focused manifest verification:
```bash
cd /mnt/DATA/git/govoplan-issue-reporting
cd /mnt/DATA/git/govoplan-tickets
PYTHONPATH=src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan-core/.venv/bin/python -m unittest discover -s tests
```
## Gitea Workflow
Issue templates are installed under `.gitea/`, and the shared label taxonomy is copied to `docs/gitea-labels.json` with the module label `module/issue-reporting`.
Issue templates are installed under `.gitea/`, and the shared label taxonomy is
copied to `docs/gitea-labels.json` with the module label `module/tickets`.
From the core checkout, labels can be synced once a local `GITEA_TOKEN` is available:
```bash
cd /mnt/DATA/git/govoplan-core
/mnt/DATA/git/govoplan/tools/gitea/gitea-sync-labels.py --root /mnt/DATA/git/govoplan-issue-reporting --apply
/mnt/DATA/git/govoplan/tools/gitea/gitea-sync-labels.py --root /mnt/DATA/git/govoplan-tickets --apply
```

View File

@@ -1,47 +0,0 @@
# Issue Reporting Domain Boundary
## Purpose
Public or internal problem reporting for broken infrastructure, damaged rooms, IT outages, safety issues, accessibility issues, triage, and routing.
## Owns
- issue intake
- problem category taxonomy
- triage and routing facts
- public reporter references
- handoff targets
## Does Not Own
- internal service desk execution
- legal case handling
- asset lifecycle management
## Integration Candidates
- helpdesk
- cases
- assets
- facilities
- forms-runtime
- portal
- files
- workflow
## Seed State
The current repository state is intentionally small:
- module manifest and entry point
- tenant-level permission definitions
- manager and viewer role templates
- documentation topic describing the module boundary
- Gitea issue workflow templates
- manifest contract test
No runtime API, database model, migration, WebUI route, or navigation item is registered yet. The first implementation slice should preserve the boundary above and only add user-visible surfaces once the workflow model is clear.
## First Implementation Slice
Define intake submission, triage status, category, location, evidence, and handoff contracts to helpdesk, cases, assets, or facilities.

View File

@@ -0,0 +1,78 @@
# Tickets Domain Boundary
## Purpose
Queue-oriented operational work: public or internal reports, service requests,
incidents, problems, triage, routing, assignment, service-level tracking, and
auditable resolution.
## Owns
- ticket identity, type, category, priority, state, and queue
- public and internal intake profiles
- reporter/requester and affected-object references
- triage, routing, assignment, escalation, and service-level facts
- discussion and resolution evidence references
- stable links to tasks, projects, assets, facilities, and cases
## Does Not Own
- formal administrative case identity, parties, evidence, decisions, and retention
- project plans, milestones, and portfolios
- asset lifecycle management
- workflow definitions and task execution
## Integration Candidates
- cases
- projects
- wiki
- assets
- facilities
- forms_runtime
- portal
- files
- workflow
- tasks
- mail
- notifications
- search
## Ticket Versus Case
A ticket is the operational record of work entering and moving through a queue.
It can be reported with incomplete information, assigned and reassigned,
discussed, resolved, reopened, or linked to another work object. Its lifecycle
answers: what needs attention, who owns the next action, and was it resolved?
A case is the authoritative procedural record for an administrative matter. It
has formal parties, evidence, decisions, procedural deadlines, access rules,
retention obligations, and a durable case history. Its lifecycle answers: what
matter is being administered, under which procedure, and what formal outcome
was reached?
Escalation does not convert or duplicate records. It creates an auditable
relation containing the ticket reference, case reference, relation type,
actor, timestamp, and optional handoff note. The ticket remains the intake and
service history; the case becomes authoritative for the formal procedure.
The former Issue Reporting and Helpdesk concepts become ticket type, intake,
queue, and policy profiles. They do not need separate persistence models.
## Seed State
The current repository state is intentionally small:
- module manifest and entry point
- tenant-level permission definitions
- manager and viewer role templates
- documentation topic describing the module boundary
- Gitea issue workflow templates
- manifest contract test
No runtime API, database model, migration, WebUI route, or navigation item is registered yet. The first implementation slice should preserve the boundary above and only add user-visible surfaces once the workflow model is clear.
## First Implementation Slice
Define ticket identity, intake profiles, queues, triage, assignment,
resolution, and stable escalation links to cases.

View File

@@ -11,6 +11,12 @@
"description": "New user-visible behavior or platform capability.",
"exclusive": true
},
{
"name": "type/user-story",
"color": "1d76db",
"description": "End-to-end user journey or real-world process story used to steer product slices.",
"exclusive": true
},
{
"name": "type/task",
"color": "1d76db",
@@ -143,6 +149,24 @@
"description": "GovOPlaN core runner, shared primitives, shell, or extension points.",
"exclusive": false
},
{
"name": "module/dashboard",
"color": "1d76db",
"description": "GovOPlaN Dashboard module behavior or integration.",
"exclusive": false
},
{
"name": "module/dataflow",
"color": "1d76db",
"description": "GovOPlaN Dataflow module behavior or integration.",
"exclusive": false
},
{
"name": "module/datasources",
"color": "006b75",
"description": "GovOPlaN governed datasource contracts, catalogs, and integrations.",
"exclusive": false
},
{
"name": "module/dms",
"color": "c5def5",
@@ -151,8 +175,14 @@
},
{
"name": "module/docs",
"color": "5319e7",
"description": "GovOPlaN documentation layer behavior or integration.",
"color": "c5def5",
"description": "GovOPlaN Docs module behavior or integration.",
"exclusive": false
},
{
"name": "module/dist-lists",
"color": "0e8a16",
"description": "GovOPlaN Distribution Lists module behavior or integration.",
"exclusive": false
},
{
@@ -161,6 +191,12 @@
"description": "GovOPlaN Erp module behavior or integration.",
"exclusive": false
},
{
"name": "module/evaluation",
"color": "bfdadc",
"description": "GovOPlaN Evaluation module behavior or integration.",
"exclusive": false
},
{
"name": "module/files",
"color": "006b75",
@@ -185,6 +221,12 @@
"description": "GovOPlaN Identity Trust module behavior or integration.",
"exclusive": false
},
{
"name": "module/identity",
"color": "bfd4f2",
"description": "GovOPlaN Identity module behavior or integration.",
"exclusive": false
},
{
"name": "module/idm",
"color": "0052cc",
@@ -215,30 +257,66 @@
"description": "GovOPlaN Ops module behavior or integration.",
"exclusive": false
},
{
"name": "module/organizations",
"color": "bfdadc",
"description": "GovOPlaN Organizations module behavior or integration.",
"exclusive": false
},
{
"name": "module/payments",
"color": "bfd4f2",
"description": "GovOPlaN Payments module behavior or integration.",
"exclusive": false
},
{
"name": "module/permits",
"color": "fbca04",
"description": "GovOPlaN Permits module behavior or integration.",
"exclusive": false
},
{
"name": "module/policy",
"color": "d93f0b",
"description": "GovOPlaN Policy module behavior or integration.",
"exclusive": false
},
{
"name": "module/poll",
"color": "e4e669",
"description": "GovOPlaN Poll module behavior or integration.",
"exclusive": false
},
{
"name": "module/portal",
"color": "1d76db",
"description": "GovOPlaN Portal module behavior or integration.",
"exclusive": false
},
{
"name": "module/postbox",
"color": "d93f0b",
"description": "GovOPlaN Postbox module behavior or integration.",
"exclusive": false
},
{
"name": "module/projects",
"color": "5319e7",
"description": "GovOPlaN Projects module behavior or integration.",
"exclusive": false
},
{
"name": "module/reporting",
"color": "c2e0c6",
"description": "GovOPlaN Reporting module behavior or integration.",
"exclusive": false
},
{
"name": "module/risk-compliance",
"color": "b60205",
"description": "GovOPlaN Risk Compliance module behavior or integration.",
"exclusive": false
},
{
"name": "module/search",
"color": "bfdadc",
@@ -270,9 +348,21 @@
"exclusive": false
},
{
"name": "module/web",
"color": "bfd4f2",
"description": "GovOPlaN public website, product page, or publication content.",
"name": "module/tickets",
"color": "0e8a16",
"description": "GovOPlaN Tickets module behavior or integration.",
"exclusive": false
},
{
"name": "module/views",
"color": "c5def5",
"description": "GovOPlaN governed task views, interface projections, and workflow view integration.",
"exclusive": false
},
{
"name": "module/wiki",
"color": "006b75",
"description": "GovOPlaN Wiki module behavior or integration.",
"exclusive": false
},
{
@@ -365,6 +455,12 @@
"description": "Versioning, release locks, tags, packaging, or dependency pins.",
"exclusive": false
},
{
"name": "area/security",
"color": "b60205",
"description": "Security posture, static analysis, supply-chain hardening, or vulnerability remediation.",
"exclusive": false
},
{
"name": "area/docs",
"color": "5319e7",
@@ -389,6 +485,48 @@
"description": "Imported from markdown backlog, roadmap, plan, or TODO files.",
"exclusive": false
},
{
"name": "source/security-audit",
"color": "d4c5f9",
"description": "Created from a structured security or code-quality audit report.",
"exclusive": false
},
{
"name": "audit/quick-fix",
"color": "0e8a16",
"description": "Audit finding that appears narrow and directly fixable.",
"exclusive": false
},
{
"name": "audit/structural",
"color": "d93f0b",
"description": "Audit finding that needs design, refactoring, or behavior review.",
"exclusive": false
},
{
"name": "audit/complexity",
"color": "fbca04",
"description": "Complexity finding from Radon, Xenon, or equivalent maintainability scans.",
"exclusive": false
},
{
"name": "audit/duplication",
"color": "c2e0c6",
"description": "Duplicated-code finding from jscpd or equivalent similarity scans.",
"exclusive": false
},
{
"name": "audit/false-positive",
"color": "cccccc",
"description": "Audit finding reviewed as a narrow false positive or acceptable risk.",
"exclusive": false
},
{
"name": "audit/needs-design",
"color": "f9d0c4",
"description": "Audit finding that needs an architectural or product decision before implementation.",
"exclusive": false
},
{
"name": "codex/ready",
"color": "0e8a16",
@@ -400,11 +538,5 @@
"color": "f9d0c4",
"description": "Needs an explicit human decision before Codex should implement.",
"exclusive": false
},
{
"name": "module/issue-reporting",
"color": "0e8a16",
"description": "GovOPlaN Issue Reporting module behavior or integration.",
"exclusive": false
}
]

View File

@@ -1,8 +1,8 @@
{
"name": "@govoplan/issue-reporting",
"name": "@govoplan/tickets",
"version": "0.1.8",
"private": true,
"description": "GovOPlaN Issue Reporting platform module seed.",
"description": "GovOPlaN Tickets platform module seed.",
"type": "module",
"peerDependencies": {}
}

View File

@@ -3,9 +3,9 @@ requires = ["setuptools>=69", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "govoplan-issue-reporting"
name = "govoplan-tickets"
version = "0.1.8"
description = "GovOPlaN Issue Reporting platform module seed."
description = "GovOPlaN Tickets platform module seed."
readme = "README.md"
requires-python = ">=3.12"
license = { file = "LICENSE" }
@@ -19,7 +19,7 @@ dependencies = [
where = ["src"]
[tool.setuptools.package-data]
govoplan_issue_reporting = ["py.typed"]
govoplan_tickets = ["py.typed"]
[project.entry-points."govoplan.modules"]
"issue-reporting" = "govoplan_issue_reporting.backend.manifest:get_manifest"
tickets = "govoplan_tickets.backend.manifest:get_manifest"

View File

@@ -1 +0,0 @@
"""GovOPlaN Issue Reporting module."""

View File

@@ -1 +0,0 @@
"""Backend integration for the GovOPlaN Issue Reporting module."""

View File

@@ -0,0 +1 @@
"""GovOPlaN Tickets module."""

View File

@@ -0,0 +1 @@
"""Backend integration for the GovOPlaN Tickets module."""

View File

@@ -3,21 +3,26 @@ from __future__ import annotations
from govoplan_core.core.access import CAPABILITY_AUTH_PERMISSION_EVALUATOR, CAPABILITY_AUTH_PRINCIPAL_RESOLVER
from govoplan_core.core.modules import DocumentationLink, DocumentationTopic, ModuleManifest, PermissionDefinition, RoleTemplate
MODULE_ID = "issue-reporting"
MODULE_NAME = "Issue Reporting"
MODULE_ID = "tickets"
MODULE_NAME = "Tickets"
MODULE_VERSION = "0.1.8"
READ_SCOPE = "issue-reporting:workspace:read"
WRITE_SCOPE = "issue-reporting:workspace:write"
ADMIN_SCOPE = "issue-reporting:workspace:admin"
READ_SCOPE = "tickets:ticket:read"
WRITE_SCOPE = "tickets:ticket:write"
ADMIN_SCOPE = "tickets:ticket:admin"
OPTIONAL_DEPENDENCIES = (
"helpdesk",
"cases",
"projects",
"wiki",
"assets",
"facilities",
"forms-runtime",
"forms_runtime",
"portal",
"files",
"workflow",
"tasks",
"mail",
"notifications",
"search",
)
@@ -27,7 +32,7 @@ def _permission(scope: str, label: str, description: str) -> PermissionDefinitio
scope=scope,
label=label,
description=description,
category="Issue Reporting",
category="Tickets",
level="tenant",
module_id=module_id,
resource=resource,
@@ -36,22 +41,34 @@ def _permission(scope: str, label: str, description: str) -> PermissionDefinitio
PERMISSIONS = (
_permission(READ_SCOPE, "View issue reporting workspace", "Read issue reporting records, configuration, and workflow context."),
_permission(WRITE_SCOPE, "Manage issue reporting workspace", "Create and update issue reporting records and workflow state."),
_permission(ADMIN_SCOPE, "Administer issue reporting workspace", "Configure issue reporting policies, templates, and tenant-level administration."),
_permission(
READ_SCOPE,
"View tickets",
"Read discoverable tickets, queue state, and resolution context.",
),
_permission(
WRITE_SCOPE,
"Manage tickets",
"Create, triage, assign, update, resolve, and link tickets.",
),
_permission(
ADMIN_SCOPE,
"Administer tickets",
"Configure ticket types, queues, service policies, and intake profiles.",
),
)
ROLE_TEMPLATES = (
RoleTemplate(
slug="issue_reporting_manager",
name="Issue Reporting manager",
description="Manage issue reporting records and workflow state.",
slug="tickets_manager",
name="Tickets manager",
description="Triage, assign, update, and resolve tickets.",
permissions=(READ_SCOPE, WRITE_SCOPE),
),
RoleTemplate(
slug="issue_reporting_viewer",
name="Issue Reporting viewer",
description="Read issue reporting records and workflow context.",
slug="tickets_viewer",
name="Tickets viewer",
description="Read discoverable tickets and their resolution context.",
permissions=(READ_SCOPE,),
),
)
@@ -60,7 +77,10 @@ DOCUMENTATION = (
DocumentationTopic(
id=f"{MODULE_ID}.module-boundary",
title=f"{MODULE_NAME} module boundary",
summary="Public or internal problem reporting for broken infrastructure, damaged rooms, IT outages, safety issues, accessibility issues, triage, and routing.",
summary=(
"Queue-oriented reports, requests, incidents, problems, triage, "
"routing, service work, and auditable resolution."
),
body=(
"This repository is currently a platform module seed. It registers the domain boundary, "
"permission surface, role templates, and documentation metadata before runtime APIs, "
@@ -74,14 +94,24 @@ DOCUMENTATION = (
links=(
DocumentationLink(
label="Repository domain boundary",
href="govoplan-issue-reporting/docs/ISSUE_REPORTING_DOMAIN_BOUNDARY.md",
href="govoplan-tickets/docs/TICKETS_DOMAIN_BOUNDARY.md",
kind="repository",
),
),
metadata={
"seed": True,
"domain_objects": ['issue intake', 'problem category taxonomy', 'triage and routing facts', 'public reporter references', 'handoff targets'],
"first_slice": "Define intake submission, triage status, category, location, evidence, and handoff contracts to helpdesk, cases, assets, or facilities.",
"domain_objects": [
"ticket",
"ticket type and queue",
"triage and routing facts",
"reporter and requester references",
"assignment and service-level state",
"resolution and escalation links",
],
"first_slice": (
"Define ticket identity, intake profiles, queues, triage, "
"assignment, resolution, and stable escalation links to cases."
),
},
),
)

View File

@@ -2,18 +2,26 @@ from __future__ import annotations
import unittest
from govoplan_issue_reporting.backend.manifest import ADMIN_SCOPE, READ_SCOPE, WRITE_SCOPE, get_manifest
from govoplan_tickets.backend.manifest import (
ADMIN_SCOPE,
READ_SCOPE,
WRITE_SCOPE,
get_manifest,
)
class ManifestSeedTests(unittest.TestCase):
def test_manifest_registers_seed_contract(self) -> None:
manifest = get_manifest()
self.assertEqual(manifest.id, "issue-reporting")
self.assertEqual(manifest.name, "Issue Reporting")
self.assertEqual(manifest.id, "tickets")
self.assertEqual(manifest.name, "Tickets")
self.assertEqual(manifest.dependencies, ("access",))
self.assertEqual({permission.scope for permission in manifest.permissions}, {READ_SCOPE, WRITE_SCOPE, ADMIN_SCOPE})
self.assertEqual({role.slug for role in manifest.role_templates}, {"issue_reporting_manager", "issue_reporting_viewer"})
self.assertEqual(
{role.slug for role in manifest.role_templates},
{"tickets_manager", "tickets_viewer"},
)
self.assertTrue(manifest.documentation)
self.assertIsNone(manifest.route_factory)
self.assertIsNone(manifest.migration_spec)