···1+<?php
2+3+namespace SocialDept\AtpParity\Contracts;
4+5+use Illuminate\Database\Eloquent\Model;
6+use SocialDept\AtpSchema\Data\Data;
7+8+/**
9+ * Contract for bidirectional mapping between Record DTOs and Eloquent models.
10+ *
11+ * @template TRecord of Data
12+ * @template TModel of Model
13+ */
14+interface RecordMapper
15+{
16+ /**
17+ * Get the Record class this mapper handles.
18+ *
19+ * @return class-string<TRecord>
20+ */
21+ public function recordClass(): string;
22+23+ /**
24+ * Get the Model class this mapper handles.
25+ *
26+ * @return class-string<TModel>
27+ */
28+ public function modelClass(): string;
29+30+ /**
31+ * Get the lexicon NSID this mapper handles.
32+ */
33+ public function lexicon(): string;
34+35+ /**
36+ * Convert a Record DTO to an Eloquent Model.
37+ *
38+ * @param TRecord $record
39+ * @param array{uri?: string, cid?: string, did?: string, rkey?: string} $meta AT Protocol metadata
40+ * @return TModel
41+ */
42+ public function toModel(Data $record, array $meta = []): Model;
43+44+ /**
45+ * Convert an Eloquent Model to a Record DTO.
46+ *
47+ * @param TModel $model
48+ * @return TRecord
49+ */
50+ public function toRecord(Model $model): Data;
51+52+ /**
53+ * Update an existing model with data from a record.
54+ *
55+ * @param TModel $model
56+ * @param TRecord $record
57+ * @param array{uri?: string, cid?: string, did?: string, rkey?: string} $meta
58+ * @return TModel
59+ */
60+ public function updateModel(Model $model, Data $record, array $meta = []): Model;
61+62+ /**
63+ * Find or create model from record.
64+ *
65+ * @param TRecord $record
66+ * @param array{uri?: string, cid?: string, did?: string, rkey?: string} $meta
67+ * @return TModel
68+ */
69+ public function upsert(Data $record, array $meta = []): Model;
70+71+ /**
72+ * Find model by AT Protocol URI.
73+ *
74+ * @return TModel|null
75+ */
76+ public function findByUri(string $uri): ?Model;
77+78+ /**
79+ * Delete model by AT Protocol URI.
80+ */
81+ public function deleteByUri(string $uri): bool;
82+}
+25
src/Data/Record.php
···0000000000000000000000000
···1+<?php
2+3+namespace SocialDept\AtpParity\Data;
4+5+use SocialDept\AtpClient\Contracts\Recordable;
6+use SocialDept\AtpSchema\Data\Data;
7+8+/**
9+ * Base class for custom AT Protocol records.
10+ *
11+ * Extends atp-schema's Data for full compatibility with the ecosystem,
12+ * including union type support, validation, equality, and hashing.
13+ *
14+ * Implements Recordable for seamless atp-client integration.
15+ */
16+abstract class Record extends Data implements Recordable
17+{
18+ /**
19+ * Get the record type (alias for getLexicon for Recordable interface).
20+ */
21+ public function getType(): string
22+ {
23+ return static::getLexicon();
24+ }
25+}