> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nihalxkumar.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Zingat Development

> Development setup and contributing guide for Zingat - Code structure, testing, and contribution process

## Development Environment Setup

### Prerequisites

* **Rust 1.56+**: Latest stable Rust version
* **Cargo**: Rust package manager
* **SQLx CLI**: For database migrations
* **Git**: Version control

### Clone Repository

```bash theme={null}
git clone https://github.com/nihalxkumar/zingat
cd zingat
```

### Install Dependencies

```bash theme={null}
# Install SQLx CLI
cargo install sqlx-cli

# Install development tools
cargo install cargo-watch  # For hot reloading
cargo install cargo-audit  # For security audits
```

<Check>
  Confirm tools with `cargo --version`, `sqlx --version`, and `cargo audit --version`.
</Check>

### Database Setup

```bash theme={null}
# Setup development database
sqlx database setup

# Run migrations
sqlx migrate run
```

### Development Database

Zingat uses SQLite for development by default. The database file is created at `data.db` in the project root (default connection string: `sqlite:data.db`).

## Codebase Structure

```
zingat/
├── src/
│   ├── bin/
│   │   ├── httpd.rs         # Web server binary
│   │   └── clipclient.rs    # CLI client binary
│   └── lib/
│       ├── data/             # Data layer
│       │   ├── mod.rs        # Database connection and configuration
│       │   ├── model.rs      # Database models and entities
│       │   └── query.rs      # Database queries and operations
│       ├── domain/           # Domain layer
│       │   ├── clip/         # Core business logic for clips
│       │   │   ├── field/    # Newtype wrappers for type safety
│       │   │   │   ├── clip_id.rs
│       │   │   │   ├── content.rs
│       │   │   │   ├── expires.rs
│       │   │   │   ├── hits.rs
│       │   │   │   ├── password.rs
│       │   │   │   ├── posted.rs
│       │   │   │   ├── shortcode.rs
│       │   │   │   └── title.rs
│       │   │   └── mod.rs    # Main Clip struct and ClipError enum
│       │   ├── maintenance.rs  # Background maintenance tasks
│       │   └── time.rs       # Time-related utilities
│       ├── service/          # Service layer
│       │   ├── action.rs     # Business logic actions
│       │   └── ask.rs        # Request/response DTOs
│       └── web/              # Web layer
│           ├── api.rs        # REST API endpoints and authentication
│           ├── ctx.rs        # Template context structures
│           ├── form.rs       # Form handling and validation
│           ├── hitcounter.rs # Asynchronous hit counting system
│           ├── http.rs       # Web UI routes and handlers
│           ├── mod.rs        # Web module exports
│           └── renderer.rs   # Template rendering engine
├── migrations/               # Database migrations
├── templates/               # Handlebars templates
│   ├── base.hbs
│   ├── home.hbs
│   ├── clip.hbs
│   ├── clip_need_password.hbs
│   ├── error_box.hbs
│   ├── header.hbs
│   └── footer.hbs
├── static/                  # Static assets
│   ├── zingat.css
│   ├── tiny-date-picker.min.js
│   └── logo.svg
├── tests/                   # Integration tests
└── Cargo.toml              # Project dependencies
```

### Key Modules

#### Data Layer (`src/lib/data/`)

* `mod.rs`: Database connection pooling and configuration
* `model.rs`: Database models matching the `clips` and `api_keys` tables
* `query.rs`: SQL queries using SQLx with prepared statements

#### Domain Layer (`src/lib/domain/`)

* `clip/mod.rs`: Core Clip struct and ClipError enum with all error variants
* `clip/field/`: Newtype wrappers for type safety (ClipId, Content, Expires, Hits, Password, Posted, Shortcode, Title)
* `maintenance.rs`: Background tasks for expired clip cleanup
* `time.rs`: Time utilities for date parsing and expiration checks

#### Service Layer (`src/lib/service/`)

* `action.rs`: Business logic for clip operations (create, read, update)
* `ask.rs`: Request/response DTOs for API operations

#### Web Layer (`src/lib/web/`)

* `api.rs`: REST API endpoints (`/api/clip/*`) with API key authentication
* `http.rs`: Web UI routes (`/`, `/clip/<shortcode>`, `/clip/raw/<shortcode>`)
* `hitcounter.rs`: Asynchronous hit counting with batching via crossbeam channels
* `form.rs`: Form handling and validation for web UI
* `renderer.rs`: Handlebars template rendering
* `ctx.rs`: Template context structures

## Development Workflow

### Running Development Server

```bash theme={null}
# Standard run
cargo run --bin httpd

# With hot reloading
cargo watch -x "run --bin httpd"

# With debug logging
RUST_LOG=debug cargo run --bin httpd
```

### Running CLI Client

```bash theme={null}
cargo run --bin clipclient
```

### Code Formatting

```bash theme={null}
# Format code
cargo fmt

# Check formatting
cargo fmt -- --check
```

### Linting

```bash theme={null}
# Run clippy linter
cargo clippy

# Run clippy with warnings
cargo clippy -- -W clippy::pedantic
```

## Testing

### Unit Tests

Run unit tests:

```bash theme={null}
cargo test
```

### Integration Tests

Integration tests are in the `tests/` directory:

```bash theme={null}
cargo test --test integration
```

### Test Coverage

Install tarpaulin for test coverage:

```bash theme={null}
cargo install cargo-tarpaulin
cargo tarpaulin --ignore-tests
```

## Templates and Static Assets

### Templates

Zingat uses Handlebars templates located in the `templates/` directory:

* **`base.hbs`**: Base template layout with common HTML structure
* **`home.hbs`**: Home page with clip creation form
* **`clip.hbs`**: Clip display page showing content and metadata
* **`clip_need_password.hbs`**: Password prompt for protected clips
* **`error_box.hbs`**: Error display component
* **`header.hbs`**: Page header component
* **`footer.hbs`**: Page footer component

Templates are rendered via the `renderer.rs` module which provides template context and error handling.

### Static Assets

Static files are served from the `static/` directory:

* **`zingat.css`**: Custom CSS styling for the web interface
* **`tiny-date-picker.min.js`**: JavaScript library for date picker functionality
* **`logo.svg`**: Zingat logo (available in light and dark variants)

Static assets are served directly by Rocket and don't require template rendering.

## Dependencies Overview

Key dependencies used in Zingat:

**Core**:

* `serde`, `serde_json`: Serialization
* `thiserror`: Error handling
* `chrono`: Date/time handling
* `uuid`: UUID generation

**Web**:

* `rocket`: Web framework (0.5.0-rc.1)
* `handlebars`: Template engine (4.x)
* `tokio`: Async runtime (1.8.0)

**Database**:

* `sqlx`: Database toolkit (0.8.2)

**CLI**:

* `structopt`: Command-line argument parsing
* `dotenv`: Environment variable loading

**Utilities**:

* `derive_more`: Additional derive macros
* `rand`: Random number generation
* `base64`: Base64 encoding/decoding
* `reqwest`: HTTP client for CLI
* `strum`: String enum conversions

**Concurrency**:

* `crossbeam-channel`: Multi-producer, multi-consumer channels for hit counter batching
* `parking_lot`: Faster mutex implementation

## Code Quality

### Security Audits

```bash theme={null}
# Check for vulnerable dependencies
cargo audit

# Update dependencies
cargo update
```

### Documentation

Generate documentation:

```bash theme={null}
# Generate docs
cargo doc --open

# Check documentation coverage
cargo doc --no-deps --document-private-items
```

### Benchmarking

Create benchmarks for performance-critical code:

```rust theme={null}
#[bench]
fn bench_paste_creation(b: &mut Bencher) {
    b.iter(|| create_test_paste());
}
```

## Code Standards

### Rust Conventions

* Follow Rust naming conventions
* Use `rustfmt` for consistent formatting
* Apply Clippy recommendations
* Document public APIs with `///` comments

### Error Handling

Zingat uses comprehensive error types with the `thiserror` crate:

**ClipError Variants** (defined in `src/lib/domain/clip/mod.rs`):

* `NotFound`: Clip doesn't exist
* `AlreadyExists`: Shortcode collision
* `Expired`: Clip has passed expiration date
* `InvalidPassword`: Wrong password provided
* `InvalidTitle`: Title validation failed
* `EmptyContent`: Content cannot be empty
* `InvalidDate`: Date parsing error

**API Errors**:

* `NotFound`: Resource not found (404)
* `Server`: Internal server error (500)
* `User`: Client error (401)
* `KeyError`: API key issues (400)

All errors implement `std::error::Error` and can be converted to appropriate HTTP responses.

### Database Operations

* Use prepared statements with SQLx
* Handle database errors appropriately
* Implement proper connection pooling

### Security

* Hash passwords with Argon2
* Validate all user input
* Implement rate limiting
* Use HTTPS in production

## Performance Considerations

### Database Optimization

* Use batch operations for view tracking
* Implement proper indexing
* Monitor query performance

### Memory Management

* Use Rust's ownership system effectively
* Avoid unnecessary allocations
* Implement proper caching

### Async Programming

* Use Tokio for async operations
* Avoid blocking calls in async context
* Implement proper error handling in async code

## Debugging

### Logging

Enable different log levels:

```bash theme={null}
RUST_LOG=debug cargo run --bin httpd
RUST_LOG=zingat=debug cargo run --bin httpd
```

<Steps>
  <Step title="Start the API server">
    Run `cargo run --bin httpd` and ensure the server listens on the expected port.
  </Step>

  <Step title="Smoke test the API">
    ```bash theme={null}
    xh POST http://localhost:8000/api/paste content='dev test' expires_in:=60
    ```
  </Step>

  <Step title="Run CLI client">
    ```bash theme={null}
    cargo run --bin clipclient
    ```
  </Step>
</Steps>

### Debugging Tools

* **println! debugging**: Simple output debugging
* **dbg! macro**: Quick value inspection
* **Rust debugger**: Use GDB or LLDB
* **Tracing**: Structured logging

### Database Inspection

```bash theme={null}
# SQLite inspection
sqlite3 zingat.db
.tables
.schema pastes
```
