📄 PublicLibraryStorage.sol
D-OPEN SOVEREIGN
1/*
2 * Copyright (c) 2026 DataPond D-Library Pty Ltd. ("The Sanctuary")
3 * Non-Profit Public Library — The World Library
4 *
5 * D-SAFE Certification issued by POND Enterprise.
6 * Published under the D-Open Code Sovereign Licence v1.0 framework
7 * DataPond D-Library All exclusive Right reserved on modifiying the code - CC Attribution to data pond, Non modifiable, Non Commercial.
8 * https://registry.world.bibliotech.com/licence
9 * Source code donated to DataPond D-Library by it's author: data pond.
10 *
11 * Technical Guardian ("The Shield"): Pond Enterprise Pty Ltd. (ACN 694 747 987)
12 * All liability claims about D-SAFE certification issues coming from the published D-Safe direction must be addressed with Pond Enterprise Pty Ltd.
13 * Code Modification automatically voids the certified liability protection provided by Pond Enterprise.
14 */
15
16// SPDX-License-Identifier: Apache-2.0
17pragma solidity ^0.8.24;
18
19import {ErrorLibrary} from "./ErrorLibrary.sol";
20
21contract PublicLibraryStorage {
22
23    enum LibraryOwnership {
24        Public,
25        Private
26    }
27
28    struct PublicLibrary {
29        uint256 id;
30        string name;
31        string physicalAddress;
32        string country;
33        string language;
34        LibraryOwnership ownership;
35        string website;
36        string preferredFormat;
37        uint64 createdAt;
38        uint64 updatedAt;
39    }
40
41    struct PublicLibraryInput {
42        string name;
43        string physicalAddress;
44        string country;
45        string language;
46        LibraryOwnership ownership;
47        string website;
48        string preferredFormat;
49    }
50
51    // State Variables
52    address public admin; // single admin or multi-sig if you choose
53    mapping(address => bool) public _isAuthorized; // reserved for future write access (unused for now)
54
55    mapping(uint256 => PublicLibrary) private libraries;
56    uint256 private _nbLibraries;
57
58    // Dynamic, admin-appendable registry of interchange/cataloging format identifiers a
59    // library or collection's preferredFormat can be validated against. Append-only, same
60    // "array + existence-map" idiom AddressRegistry uses for _contractNames/_dataKeys/_blobRefKeys.
61    string[] private _formats;
62    mapping(string => bool) private _formatExists;
63
64    event AuthorizedAdded(address indexed caller);
65    event AuthorizedRemoved(address indexed caller);
66    event PublicLibraryAdded(uint256 indexed id, string name);
67    event PublicLibraryUpdated(uint256 indexed id);
68    event FormatAdded(string format);
69
70    // Modifiers
71    modifier onlyAdmin() {
72        require(msg.sender == admin, "not admin");
73        _;
74    }
75
76    modifier onlyAuthorized() {
77        require(_isAuthorized[msg.sender], "not authorized");
78        _;
79    }
80
81    constructor() {
82        admin = msg.sender;
83    }
84
85    // ===== Admin / authorization (reserved for future write access) =====
86    function isAuthorized(address caller) public view returns (bool) {
87        require(caller != address(0), "zero addr");
88        return _isAuthorized[caller];
89    }
90
91    function addAuthorized(address caller) public onlyAdmin {
92        require(caller != address(0), "zero addr");
93        _isAuthorized[caller] = true;
94        emit AuthorizedAdded(caller);
95    }
96
97    function removeAuthorized(address caller) public onlyAdmin {
98        _isAuthorized[caller] = false;
99        emit AuthorizedRemoved(caller);
100    }
101
102    // ===== Format registry (admin-appendable, never removed) =====
103    function addFormat(string calldata format) external onlyAdmin {
104        require(bytes(format).length > 0, "PublicLibraryStorage: empty format");
105        require(!_formatExists[format], "PublicLibraryStorage: format exists");
106        _formatExists[format] = true;
107        _formats.push(format);
108        emit FormatAdded(format);
109    }
110
111    function formatExists(string calldata format) public view returns (bool) {
112        return _formatExists[format];
113    }
114
115    function getAllFormats() external view returns (string[] memory) {
116        return _formats;
117    }
118
119    // ===== Public library lifecycle (admin-only for now) =====
120    function addPublicLibrary(PublicLibraryInput calldata input) external onlyAdmin returns (uint256 id) {
121        if (!formatExists(input.preferredFormat)) revert ErrorLibrary.InvalidFormat();
122
123        _nbLibraries++;
124        id = _nbLibraries;
125
126        uint64 nowTs = uint64(block.timestamp);
127
128        libraries[id] = PublicLibrary({
129            id: id,
130            name: input.name,
131            physicalAddress: input.physicalAddress,
132            country: input.country,
133            language: input.language,
134            ownership: input.ownership,
135            website: input.website,
136            preferredFormat: input.preferredFormat,
137            createdAt: nowTs,
138            updatedAt: nowTs
139        });
140
141        emit PublicLibraryAdded(id, input.name);
142    }
143
144    function updatePublicLibrary(uint256 id, PublicLibraryInput calldata input) external onlyAdmin {
145        if (!libraryExists(id)) revert ErrorLibrary.InvalidPublicLibraryId();
146        if (!formatExists(input.preferredFormat)) revert ErrorLibrary.InvalidFormat();
147
148        PublicLibrary storage lib = libraries[id];
149        lib.name = input.name;
150        lib.physicalAddress = input.physicalAddress;
151        lib.country = input.country;
152        lib.language = input.language;
153        lib.ownership = input.ownership;
154        lib.website = input.website;
155        lib.preferredFormat = input.preferredFormat;
156        lib.updatedAt = uint64(block.timestamp);
157
158        emit PublicLibraryUpdated(id);
159    }
160
161    // ===== Reads =====
162    function libraryExists(uint256 id) public view returns (bool) {
163        return id > 0 && id <= _nbLibraries;
164    }
165
166    function getPublicLibrary(uint256 id) external view returns (PublicLibrary memory) {
167        if (!libraryExists(id)) revert ErrorLibrary.InvalidPublicLibraryId();
168        return libraries[id];
169    }
170
171    function nbLibraries() external view returns (uint256) {
172        return _nbLibraries;
173    }
174}
175