08-full-application

command module
v0.0.0-...-f718705 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

README

Example 08: Full Application

A production-ready collaborative task management platform demonstrating comprehensive NCore features including multi-tenancy, real-time communication, event-driven architecture, authentication, background jobs, and WebSocket integration.

Overview

This example showcases a complete, production-ready application combining all NCore patterns from previous examples into a cohesive system. It implements a collaborative task management platform with:

  • Multi-tenant Architecture: Workspaces for isolation and team management
  • Real-time Updates: WebSocket-based live collaboration
  • Event-Driven Communication: Modules communicate via event bus
  • JWT Authentication: Secure token-based auth with refresh tokens
  • Background Processing: Async job execution for exports
  • Email Notifications: Event-driven email alerts

Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                         Application Server                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────┐     ┌──────────┐     ┌──────────┐    │
│  │   Core    │     │   Biz    │     │  Plugin   │    │
│  │  Modules  │     │  Modules  │     │  Modules  │    │
│  │           │     │           │     │           │    │
│  │ • auth    │     │ • task    │     │ • notify  │    │
│  │ • user    │◄───►│ • comment │◄───►│ • export  │    │
│  │ • workspace│     │ • realtime│     │           │    │
│  └──────────┘     └──────────┘     └──────────┘    │
│         │                │                   │              │
│         │                │                   │              │
│         ▼                ▼                   ▼              │
│  ┌───────────────────────────────────────────────────────┐        │
│  │              Event Bus (Pub/Sub)               │        │
│  └───────────────────────────────────────────────────────┘        │
│         │                │                   │                       │
│         ▼                ▼                   ▼                       │
│  ┌──────────┐     ┌──────────┐     ┌──────────┐        │
│  │WebSocket │     │  Worker   │     │   Email   │        │
│  │   Hub    │     │   Pool    │     │  Sender   │        │
│  └──────────┘     └──────────┘     └──────────┘        │
└─────────────────────────────────────────────────────────────────────────┘

Features Demonstrated

1. Multi-Tenancy with Workspaces
  • Workspace isolation for different teams/organizations
  • Member management with role-based permissions (owner, admin, member)
  • Workspace-scoped resources (tasks, comments)
2. Real-Time WebSocket Communication
  • Room-based broadcasting by workspace
  • Live updates for tasks and comments
  • Connection management and graceful disconnects
  • Ping/pong for connection health
3. Event-Driven Architecture
  • Inter-module communication via event bus
  • Async event processing with worker pool
  • Event sourcing capabilities
  • Workspace-scoped events
4. JWT Authentication & RBAC
  • Token-based authentication with JWT
  • Access and refresh token pattern
  • Role-based authorization (user, admin)
  • Middleware for protected routes
5. Background Job Processing
  • Export jobs (CSV, JSON)
  • Job status tracking (pending, running, completed, failed)
  • Worker pool for concurrent execution
  • Progress updates via events
6. Email Notifications
  • Event-driven email notifications
  • Task creation alerts
  • Task assignment notifications
  • Comment notifications

Project Structure

08-full-application/
├── main.go                         # Application entry point
├── core/                           # Core domain modules
│   ├── auth/
│   │   ├── auth.go                 # Auth module
│   │   ├── service/
│   │   │   └── service.go          # Auth business logic
│   │   └── middleware/
│   │       └── middleware.go       # JWT middleware
│   ├── user/
│   │   ├── user.go                 # User module
│   │   ├── handler/
│   │   │   └── handler.go          # User HTTP handlers
│   │   ├── service/
│   │   │   └── service.go          # User business logic
│   │   ├── structs/
│   │   │   └── structs.go          # User structs
│   │   └── data/
│   │       ├── generate.go         # Ent generation entrypoint
│   │       ├── schema/
│   │       │   └── user.go         # Ent schema
│   │       ├── ent/                # Generated Ent client
│   │       └── repository/
│   │           └── repository.go   # Postgres user repo (Ent)
│   └── workspace/
│       ├── workspace.go            # Workspace module
│       ├── structs/
│       │   └── structs.go          # Workspace structs
│       └── data/repository/
│           └── repository.go       # Postgres workspace repo
├── biz/                            # Business domain modules
│   ├── task/
│   │   ├── task.go                 # Task module
│   │   ├── structs/
│   │   │   └── structs.go          # Task structs
│   │   └── data/repository/
│   │       └── repository.go       # Postgres task repo
│   ├── comment/
│   │   ├── comment.go              # Comment module
│   │   ├── structs/
│   │   │   └── structs.go          # Comment structs
│   │   └── data/repository/
│   │       └── repository.go       # Postgres comment repo
│   └── realtime/
│       └── realtime.go             # WebSocket hub & handlers
├── plugin/                         # Plugin modules
│   ├── notification/
│   │   └── notification.go         # Email notification plugin
│   └── export/
│       ├── export.go               # Export job plugin
│       ├── structs/
│       │   └── structs.go          # Export job structs
│       └── data/repository/
│           └── repository.go       # Mongo export job repo
├── internal/
│   ├── event/
│   │   └── bus.go                  # Event bus implementation
│   └── server/
│       └── server.go               # Server & extension manager
├── config.yaml                      # Application configuration
├── go.mod
└── README.md

Module Descriptions

Core Modules
Auth Module (core/auth)
  • User registration with password validation
  • JWT token generation and validation
  • Login with email/password
  • Token refresh mechanism
  • Authentication middleware
  • Role-based authorization middleware
User Module (core/user)
  • User CRUD operations
  • User listing with pagination
  • Role management (user, admin)
Workspace Module (core/workspace)
  • Workspace CRUD operations
  • Member management (add/remove)
  • Role-based access control (owner, admin, member)
  • Workspace listing for users
Business Modules
Task Module (biz/task)
  • Task CRUD operations
  • Task assignment to users
  • Status tracking (pending, in_progress, completed)
  • Priority management (low, medium, high)
  • Workspace-scoped tasks
  • Event emission on all operations
Comment Module (biz/comment)
  • Comment CRUD operations
  • Task-comment relationship
  • Ownership-based update/delete
  • Event emission on all operations
Realtime Module (biz/realtime)
  • WebSocket connection management
  • Room-based broadcasting by workspace
  • Event subscription and forwarding
  • Connection health monitoring
  • Hub statistics
Plugin Modules
Notification Plugin (plugin/notification)
  • Event-driven email notifications
  • Task creation alerts
  • Task assignment notifications
  • Comment notifications
  • Email template support
Export Plugin (plugin/export)
  • Background export jobs (CSV, JSON)
  • Task and comment export
  • Job status tracking
  • Progress updates via events
  • Worker pool integration

Configuration

server:
  host: 0.0.0.0
  port: 8080
  mode: debug

data:
  database:
    master:
      driver: postgres
      source: "host=localhost port=5432 user=postgres password=postgres dbname=fullappdb sslmode=disable"
      max_idle_conns: 10
      max_open_conns: 100
  mongodb:
    master:
      uri: "mongodb://localhost:27017/fullappdb"
      logging: false
    strategy: "round_robin"
    max_retry: 3
  redis:
    addr: "localhost:6379"
    db: 0
    read_timeout: 3s
    write_timeout: 3s
    dial_timeout: 5s

auth:
  jwt:
    secret: "your-secret-key-change-in-production"
    access_token_ttl: 900 # 15 minutes
    refresh_token_ttl: 604800 # 7 days
  password:
    min_length: 8
    require_uppercase: true
    require_number: true

worker:
  pool_size: 10
  queue_size: 1000
  shutdown_timeout: 30

email:
  smtp:
    host: "smtp.gmail.com"
    port: "587"
    username: "noreply@example.com"
    password: "your-smtp-password"
    from: "noreply@example.com"

logger:
  level: debug
  format: json
  output: stdout

API Endpoints

Authentication
POST   /auth/register    # Register new user
POST   /auth/login       # Login and get tokens
POST   /auth/refresh     # Refresh access token
POST   /auth/logout      # Logout
Users
POST   /users                # Create user (admin)
GET    /users                # List users (admin)
GET    /users/:user_id            # Get user by ID
PUT    /users/:user_id            # Update user
DELETE /users/:user_id            # Delete user
Workspaces
POST   /workspaces                    # Create workspace
GET    /workspaces                    # List workspaces for user
GET    /workspaces/:workspace_id      # Get workspace by ID
POST   /workspaces/:workspace_id/members        # Add member
GET    /workspaces/:workspace_id/members        # List members
Tasks
POST   /workspaces/:workspace_id/tasks   # Create task in workspace
GET    /workspaces/:workspace_id/tasks   # List tasks in workspace
GET    /tasks/:task_id                      # Get task by ID
PUT    /tasks/:task_id                      # Update task
DELETE /tasks/:task_id                      # Delete task
POST   /tasks/:task_id/assign               # Assign task to user
Comments
POST   /workspaces/:workspace_id/comments   # Create comment
GET    /tasks/:task_id/comments         # List comments for task
GET    /comments/:comment_id                   # Get comment by ID
PUT    /comments/:comment_id                   # Update comment
DELETE /comments/:comment_id                   # Delete comment
Real-time (WebSocket)
GET    /ws/:workspace_id    # WebSocket connection for workspace
Exports
POST   /workspaces/:workspace_id/exports   # Create export job
GET    /workspaces/:workspace_id/exports   # List export jobs
GET    /exports/:job_id                  # Get export job status
System
GET    /health               # Health check
GET    /events/stats         # Event bus statistics
GET    /realtime/stats      # WebSocket hub statistics

Event Flow Examples

Task Creation Flow
User creates task
    ↓
Task Service saves task to database
    ↓
Task Service publishes "task.created" event
    ↓
┌─────────────────┬─────────────────┐
│                 │                 │
▼                 ▼                 ▼
WebSocket Hub   Email Notification  Event Store
Broadcasts to    Sends email       Persists
Workspace        to members
Comment Creation Flow
User adds comment
    ↓
Comment Service saves comment to database
    ↓
Comment Service publishes "comment.created" event
    ↓
┌─────────────────┬─────────────────┐
│                 │                 │
▼                 ▼                 ▼
WebSocket Hub   Email Notification  Event Store
Broadcasts to    Sends email       Persists
Workspace
Export Job Flow
User requests export
    ↓
Export Service creates job (status: pending)
    ↓
Job submitted to Worker Pool
    ↓
Job status: running
    ↓
Worker executes export (CSV/JSON)
    ↓
Job status: completed (or failed)
    ↓
Service publishes "export.completed" event

Running the Application

Prerequisites
  • Go 1.21+
  • PostgreSQL 14+
  • MongoDB 6+
  • Redis 7+
Installation
# Navigate to example directory
cd 08-full-application

# Download dependencies
go mod download

# Generate Ent client for user module
go generate ./core/user/data

# Run the application
go run main.go -config config.yaml
Usage
# Start the application
go run main.go

# Application will start on http://localhost:8080

# Check health
curl http://localhost:8080/health

# View event bus stats
curl http://localhost:8080/events/stats

# View WebSocket stats
curl http://localhost:8080/realtime/stats

API Examples

Register User
curl -X POST http://localhost:8080/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john@example.com",
    "password": "SecurePass123"
  }'

# Response:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "John Doe",
  "email": "john@example.com",
  "role": "user",
  "created_at": "2024-01-15T12:00:00Z"
}
Login
curl -X POST http://localhost:8080/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "password": "SecurePass123"
  }'

# Response:
{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
  "expires_in": 900,
  "token_type": "Bearer"
}
Create Workspace
curl -X POST http://localhost:8080/workspaces \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{
    "name": "Engineering Team",
    "description": "Engineering workspace"
  }'
Create Task
curl -X POST http://localhost:8080/workspaces/{workspace_id}/tasks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{
    "title": "Implement new feature",
    "description": "Add the new feature to the application",
    "priority": "high",
    "status": "pending"
  }'
Add Comment
curl -X POST http://localhost:8080/workspaces/{workspace_id}/comments \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{
    "task_id": "{task_id}",
    "content": "This looks good, let's proceed"
  }'
Request Export
curl -X POST http://localhost:8080/workspaces/{workspace_id}/exports \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{
    "type": "tasks",
    "format": "csv"
  }'

# Response:
{
  "id": "job-id",
  "type": "tasks",
  "format": "csv",
  "status": "pending",
  "created_at": "2024-01-15T12:00:00Z"
}
WebSocket Connection
// Connect to workspace WebSocket
const ws = new WebSocket(
  "ws://localhost:8080/ws/{workspace_id}?token={access_token}"
);

// Listen for events
ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log("Event received:", message);

  // Message format:
  // {
  //   "type": "task.created",
  //   "workspace_id": "...",
  //   "user_id": "...",
  //   "data": { ... },
  //   "timestamp": 1234567890
  // }
};

// Send message to workspace
ws.send(
  JSON.stringify({
    type: "custom.message",
    data: {
      text: "Hello workspace!",
    },
  })
);

Key Patterns Demonstrated

1. Extension Architecture

All modules implement the extension.Extension interface:

type Module struct {
    name    string
    service *Service
    logger  *logger.Logger
}

func (m *Module) Init(ctx context.Context, deps extension.Dependencies) error
func (m *Module) PostInit(ctx context.Context) error
func (m *Module) Name() string
func (m *Module) Routes() []extension.Route
func (m *Module) Cleanup(ctx context.Context) error
2. Event-Driven Communication

Modules communicate via the event bus:

// Publish event
s.bus.Publish(ctx, &event.Event{
    Type:          event.EventTypeTaskCreated,
    AggregateID:   task.ID,
    WorkspaceID:   task.WorkspaceID,
    Payload: map[string]interface{}{
        "task_id": task.ID,
        "title": task.Title,
    },
})

// Subscribe to event
s.bus.Subscribe(event.EventTypeTaskCreated, func(ctx context.Context, evt *event.Event) error {
    // Handle event
    return nil
})
3. Multi-Tenancy Pattern

Workspace isolation ensures data separation:

// All operations are workspace-scoped
func (s *Service) CreateTask(ctx context.Context, workspaceID string, req *CreateTaskRequest) (*Task, error) {
    task := &Task{
        WorkspaceID: workspaceID,
        // ... other fields
    }
    // ...
}
4. Two-Phase Initialization

Extensions support dependency resolution:

// Phase 1: Init - All extensions initialized
if err := manager.Init(ctx); err != nil {
    return err
}

// Phase 2: PostInit - All extensions ready
if err := manager.PostInit(ctx); err != nil {
    return err
}

Production Considerations

Database Migration

Use Postgres for core data, MongoDB for events/exports, and Redis for caching. For production:

  1. Create database migrations for Postgres tables
  2. Validate MongoDB indexes for event and export collections
  3. Use transaction support for complex operations
  4. Add indexes for workspace and task queries
Authentication Security

For production:

  • Use strong JWT secrets (environment variables)
  • Implement refresh token rotation
  • Add rate limiting to auth endpoints
  • Implement CAPTCHA for registration
  • Add password reset flow
WebSocket Scaling

For production:

  • Use Redis Pub/Sub for multi-instance deployments
  • Implement connection limits per user
  • Add reconnection logic with backoff
  • Use message queue for high-throughput scenarios
Email Configuration

For production:

  • Use SMTP with TLS
  • Configure DKIM/SPF records
  • Implement email queue for rate limiting
  • Add unsubscribe functionality
Monitoring

Add observability:

  • Metrics for event bus (published/processed/failed)
  • Metrics for WebSocket connections
  • Metrics for job queue (pending/running/completed)
  • Structured logging with correlation IDs

Testing

# Unit tests
go test ./...

# Integration tests
go test -tags=integration ./...

# Coverage
go test -cover ./...

# Benchmark
go test -bench=. -benchmem

Real-World Application Patterns

This example incorporates patterns from actual NCore-based applications:

Application Pattern Implementation

NCore Modules Used

Module Usage
config Configuration management
logging Structured logging
extension/manager Module registration and lifecycle
security/jwt JWT token generation and validation
concurrency/worker Background job processing
email Email sending (notifications)
event Custom event bus implementation

Next Steps

License

This example is part of the NCore project.

Documentation

Overview

Package main boots the full application example.

Directories

Path Synopsis
biz
comment
Package comment wires comment module routes and services.
Package comment wires comment module routes and services.
comment/data/repository
Package repository stores comments for the full application example.
Package repository stores comments for the full application example.
comment/service
Package service contains comment business logic for the full app.
Package service contains comment business logic for the full app.
comment/structs
Package structs defines comment domain models for the full app.
Package structs defines comment domain models for the full app.
realtime
Package realtime provides WebSocket collaboration for the full app.
Package realtime provides WebSocket collaboration for the full app.
task
Package task defines task module wiring and routes.
Package task defines task module wiring and routes.
task/data/repository
Package repository stores tasks for the full application example.
Package repository stores tasks for the full application example.
task/service
Package service contains task business logic for the full app.
Package service contains task business logic for the full app.
task/structs
Package structs defines task domain models for the full app.
Package structs defines task domain models for the full app.
core
auth
Package auth provides authentication and authorization modules.
Package auth provides authentication and authorization modules.
auth/middleware
Package middleware provides JWT middleware for the full app.
Package middleware provides JWT middleware for the full app.
auth/service
Package service contains auth business logic for the full app.
Package service contains auth business logic for the full app.
user
Package user defines user module routes and wiring.
Package user defines user module routes and wiring.
user/data
Run: go generate ./...
Run: go generate ./...
user/data/repository
Package repository stores users for the full application example.
Package repository stores users for the full application example.
user/handler
Package handler provides user HTTP handlers for the full app.
Package handler provides user HTTP handlers for the full app.
user/service
Package service contains user business logic for the full app.
Package service contains user business logic for the full app.
user/structs
Package structs defines user domain models for the full app.
Package structs defines user domain models for the full app.
workspace
Package workspace defines workspace module routing and wiring.
Package workspace defines workspace module routing and wiring.
workspace/data/repository
Package repository stores workspaces and members for the full app.
Package repository stores workspaces and members for the full app.
workspace/service
Package service contains workspace business logic for the full app.
Package service contains workspace business logic for the full app.
workspace/structs
Package structs defines workspace domain models for the full app.
Package structs defines workspace domain models for the full app.
internal
event
Package event provides the domain event bus and stores.
Package event provides the domain event bus and stores.
server
Package server wires the full application server and extensions.
Package server wires the full application server and extensions.
plugin
export
Package export provides background export jobs for the full app.
Package export provides background export jobs for the full app.
export/data/repository
Package repository stores export jobs for the full application example.
Package repository stores export jobs for the full application example.
export/service
Package service contains export job business logic.
Package service contains export job business logic.
export/structs
Package structs defines export job domain models.
Package structs defines export job domain models.
notification
Package notification implements email notifications for the full app.
Package notification implements email notifications for the full app.
notification/service
Package service handles notification delivery for the full app.
Package service handles notification delivery for the full app.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL