This document outlines a proposed directory and file structure for features generated by petrock. The goal is to provide a more modular, maintainable organization as features grow in complexity.
feature_template/
├── main.go # Main feature package exports and initialization
│
├── assets/
│ └── keep.txt
│
├── commands/
│ ├── base.go # Common command interfaces and helpers
│ ├── create.go # Create commands
│ ├── update.go # Update commands
│ ├── delete.go # Delete commands
│ ├── request_summary.go # Request summary generation commands
│ ├── set_summary.go # Set generated summary commands
│ └── fail_summary.go # Failed summary generation commands
│
├── handlers/
│ ├── base.go # Common handler utilities and types
│ ├── middleware.go # Common middleware functions
│ ├── create_item.go # Item creation handlers (API)
│ ├── create_form.go # Form handlers for item creation (UI)
│ ├── read_item.go # Single item detail handlers
│ ├── read_list.go # List view handlers
│ ├── update_item.go # Item update handlers (API)
│ ├── update_form.go # Form handlers for item updates (UI)
│ ├── delete_item.go # Item deletion handlers (API)
│ └── delete_form.go # Confirmation forms for deletion (UI)
│
├── queries/
│ ├── base.go # Common query interfaces and types
│ ├── get.go # Query and result type for single items
│ └── list.go # Query and result types for item lists
│
├── state/
│ ├── main.go # Main state container and interfaces
│ ├── item.go # Core item state
│ └── metadata.go # Related metadata state
│
├── ui/
│ ├── components/ # Reusable UI components
│ │ ├── buttons.go # Button components and actions
│ │ ├── forms.go # Form input components
│ │ ├── tables.go # Table and list components
│ │ └── alerts.go # Alert and notification components
│ ├── layouts/ # Page layouts
│ │ ├── main.go # Standard page layout
│ │ └── modal.go # Modal dialog layouts
│ ├── pages/ # Complete page views
│ │ ├── list.go # List view for multiple items
│ │ ├── detail.go # Detail view for single item
│ │ ├── edit.go # Edit form view
│ │ ├── new.go # New item form view
│ │ └── delete.go # Delete confirmation view
│ └── helpers.go # View helper functions and utilities
│
├── routes/
│ ├── main.go # Central route registration
│ ├── api.go # API routes (REST endpoints)
│ ├── web.go # Web UI routes (HTML pages)
│ └── webhooks.go # Webhook routes (external integrations)
│
└── workers/
├── main.go # Common worker interfaces and building blocks
├── summary_worker.go # Complete worker for handling summary generation
└── types.go # Shared worker type definitions
This structure provides several advantages:
- Organization by responsibility: Code is grouped based on its functional responsibility
- Improved maintainability: Related code is co-located, making it easier to find and modify
- Scalability: The structure accommodates growth in each area without creating massive files
- Discoverability: The directory structure clearly communicates the architecture
- Separation of concerns: Distinct boundaries between different aspects of the feature
When transitioning to this structure:
- The main package file (main.go) should re-export all necessary components to maintain compatibility
- Cross-package references should use proper import paths
- Common interfaces and types should be defined in the appropriate base.go files
- Domain-specific implementations should go in specialized subdirectories
This approach maintains the command/query separation pattern and event sourcing model that's core to petrock while providing better organization for complex features.
The current feature template uses a flat directory structure with the following files:
feature_template/
├── assets.go
├── commands.go
├── execute.go
├── http.go
├── queries.go
├── query.go
├── register.go
├── routes.go
├── state.go
├── view.go
├── worker.go
└── assets/
└── keep.txt
Here's how the files in the current structure map to the new structure:
| Current File | New Location | Notes |
|---|---|---|
assets.go |
Remains at root level | Minor change, still handles asset registration |
commands.go |
commands/ directory |
Split into multiple files by command type |
execute.go |
commands/ directory |
Implementation logic moved alongside command definitions |
http.go |
handlers/ directory |
Split into multiple files by handler purpose |
queries.go |
queries/ directory |
Split into multiple files by query type |
query.go |
queries/ directory |
Implementation logic moved alongside query definitions |
register.go |
main.go |
Registration logic centralized in main package file |
routes.go |
routes/ directory |
Split into multiple files by route type |
state.go |
state/ directory |
Split into multiple files by entity type |
view.go |
ui/ directory |
Split into multiple files by component purpose |
worker.go |
workers/ directory |
Split into multiple files by worker responsibility |
The key differences are:
-
Flat vs. Hierarchical: The current structure uses a flat organization with all files in the root directory, while the new structure introduces a hierarchy that better reflects the feature's architecture.
-
File Size Management: The current structure tends to produce large files as features grow (e.g., http.go at 784 lines, view.go at 623 lines, worker.go at 426 lines). The new structure distributes this code across multiple smaller, focused files.
-
Domain Organization: The new structure allows for domain-specific organization within each subsystem (commands, queries, etc.), making it easier to locate related functionality and understand the relationships between components.
-
Discoverability: The directory structure itself communicates the architecture more clearly than the flat file structure, making it easier for new developers to understand the codebase.
-
Maintenance: With smaller, more focused files, maintenance becomes easier as changes are more isolated and have clearer boundaries.