# Phase 1: Types & Errors — COMPLETED

## Goal
Establish the shared domain types and unified error type that every subsystem depends on.

## Files
- `src/types.rs`
- `src/error.rs`

## Completed Work

### types.rs
- [x] `NamespaceId` — newtype with `Display`, `FromStr` (rejects empty strings)
- [x] `TopicName` — newtype with `Display`, `FromStr` (rejects empty strings)
- [x] `ApiKey` — newtype with `Display`, `FromStr` (rejects empty strings)
- [x] `MessageId(u64)` — `Copy` newtype with `Display`, used for ack tracking
- [x] `ClientId(u64)` — `Copy` newtype with `Display`, used for per-connection identity
- [x] `Permission` enum — Subscribe, Publish, Query (`Copy`)
- [x] `MessageEnvelope` — id, namespace, topic, payload, timestamp (`SystemTime`)
- [x] All types derive `Serialize`, `Deserialize` for storage/codec use
- [x] 18 unit tests covering Display/FromStr roundtrips, empty rejection, field construction, offset operations, PublishedMessage

### error.rs
- [x] Unified `Error` enum with `thiserror`: NamespaceNotFound, TopicNotFound, AuthFailed, PermissionDenied, Codec, Storage, Config, Serialization
- [x] `From<std::io::Error>` → `Error::Storage`
- [x] `From<serde_json::Error>` → `Error::Serialization`
- [x] `From<toml::de::Error>` → `Error::Config`
- [x] `Result<T>` type alias
- [x] 5 unit tests covering display messages and all `From` conversions

## Additions Required (post-completion)

The indexed log redesign (plan 6) requires a new type that was not part of the original types phase.

### TopicOffset type
- [x] `TopicOffset(u64)` — `Copy` newtype with `Display`, used for per-topic sequential message positioning within the indexed log
- [x] Distinct from `MessageId` — `MessageId` identifies a message globally for ack tracking; `TopicOffset` is the position of a message within a specific topic's log
- [x] Derives: `Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize`
- [x] `PartialOrd`/`Ord` needed for offset comparison in GC/compaction logic
- [x] Unit tests: Display roundtrip, ordering, construction

### GroupName type
- [x] `GroupName` — newtype (like `TopicName`), validated non-empty string
- [x] Derives: `Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Display, FromStr`
- [x] Unit tests: Display/FromStr roundtrip, empty rejection

### MessageEnvelope update
- [x] `MessageEnvelope` has no offset field — represents pre-publish state
- [x] `PublishedMessage` struct pairs `MessageEnvelope` + `TopicOffset` — represents post-publish state with guaranteed offset

## Design Decisions Made
- `MessageId` and `ClientId` are `u64`-based and `Copy` — monotonic counters, not UUIDs (simpler, faster, sufficient for single-server)
- `FromStr` impls use `Error::Config` variant for validation failures — these are input validation errors
- Timestamp uses `std::time::SystemTime` directly — no custom wrapper needed
- `serde_json` added as explicit dependency for the `From` impl

## Test Summary
- 23 unit tests (18 types + 5 error), all passing
- `cargo clippy` clean, `cargo fmt` clean
