Skip to content

Commit bd77f2f

Browse files
author
Christian Kolb
committed
Add initial claude integration
1 parent e146db2 commit bd77f2f

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

CLAUDE.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
A Symfony bundle (`digital-craftsman/date-time-precision`) providing precise date/time value objects as thin wrappers over PHP's `DateTimeImmutable`. The core idea: instead of using `DateTime` for everything, use specific value objects (`Moment`, `Date`, `Time`, `Month`, `Year`, `Day`, `Weekday`, `Weekdays`) that carry only the data they represent.
8+
9+
All value objects are `final readonly` and immutable. The system assumes UTC internally; timezone-aware operations convert temporarily to the target timezone for the operation, then back to UTC.
10+
11+
## Commands
12+
13+
All commands run via Docker Compose (PHP 8.4 and 8.5 containers). Use `make` to see all targets.
14+
15+
```bash
16+
# Run tests (both PHP versions)
17+
make php-tests
18+
19+
# Run tests for a single PHP version
20+
make php-8.4-tests
21+
make php-8.5-tests
22+
23+
# Run a single test file directly
24+
docker compose run --rm php-8.5 ./vendor/bin/phpunit tests/Moment/CompareToTest.php
25+
26+
# Run a single test method
27+
docker compose run --rm php-8.5 ./vendor/bin/phpunit --filter test_method_name tests/Moment/CompareToTest.php
28+
29+
# Code style fix + Psalm static analysis
30+
make php-code-validation
31+
32+
# Mutation testing (requires 100% MSI)
33+
make php-mutation-testing
34+
35+
# Full verification (code validation + tests + mutation testing)
36+
make verify
37+
38+
# Install dependencies
39+
make install
40+
```
41+
42+
## Architecture
43+
44+
### Value Object Hierarchy
45+
46+
- **`Moment`** — wraps `DateTimeImmutable`, represents a specific point in time (always UTC). Primary entry point with `fromString()`, `fromStringInTimeZone()`, `fromDateTime()`.
47+
- **`Date`** — composed of `Month` + `Day`. No timezone, no time component.
48+
- **`Month`** — composed of `Year` + month int (1-12).
49+
- **`Year`** — single int value.
50+
- **`Day`** — single int value (1-31).
51+
- **`Time`** — hour/minute/second/microsecond.
52+
- **`Weekday`** / **`Weekdays`** — day-of-week enum-like values.
53+
54+
All value objects implement `StringNormalizable` / `NullableStringDenormalizable` (from `digital-craftsman/self-aware-normalizers`) for Symfony serializer integration, and `NormalizableTypeWithSQLDeclaration` for Doctrine type integration.
55+
56+
### Comparison Pattern
57+
58+
Each value object has comparison methods (`isAfter`, `isBefore`, `isEqualTo`, etc.) and assertion methods (`mustBeAfter`, `mustBeBefore`, etc.) that throw typed exceptions from `src/Exception/`. The exception classes follow the naming pattern `{Type}Is{Condition}` (e.g., `MomentIsAfter`, `DateIsBefore`). Assertion methods accept a custom exception class parameter to allow domain-specific exceptions.
59+
60+
### Timezone-Aware Operations
61+
62+
`Moment` provides `*InTimeZone` method variants (e.g., `modifyInTimeZone`, `isBeforeInTimeZone`) that accept a `\DateTimeZone` parameter. These convert internally for the operation, keeping the result in UTC.
63+
64+
### Integrations
65+
66+
- **Doctrine types** in `src/Doctrine/` — one type per value object, auto-registered via `DoctrineTypeRegisterCompilerPass`.
67+
- **Symfony bundle**`DateTimePrecisionBundle` with `DateTimePrecisionExtension`.
68+
- **Clock**`Clock` interface with `SystemClock` (production) and `FrozenClock` (testing), autowired by the bundle.
69+
70+
## Code Style
71+
72+
- PHP CS Fixer with `@Symfony` ruleset (config in `.php-cs-fixer.dist.php`)
73+
- Test method names use **snake_case** (enforced by php-cs-fixer)
74+
- No Yoda comparisons
75+
- Psalm for static analysis (config in `psalm.xml`)
76+
- Mutation testing via Infection with **100% MSI required**
77+
78+
## Test Structure
79+
80+
Tests mirror the source structure: `tests/{ValueObject}/{MethodName}Test.php`. Custom test exception classes live in `tests/Test/Exception/`.

0 commit comments

Comments
 (0)