From 18f8f0e1d11ae42abcc3268abb94d01c480208e7 Mon Sep 17 00:00:00 2001 From: Sebastian Krupinski Date: Tue, 17 Feb 2026 03:09:38 -0500 Subject: [PATCH] chore: standardize chrono provider Signed-off-by: Sebastian Krupinski --- .../Collection/CollectionBaseAbstract.php | 31 +++ .../Collection/CollectionBaseInterface.php | 30 +++ .../Collection/CollectionMutableAbstract.php | 50 +++++ .../Collection/CollectionMutableInterface.php | 32 +++ .../Collection/CollectionPermissions.php | 26 --- .../CollectionPropertiesBaseAbstract.php | 76 +++++++ .../CollectionPropertiesBaseInterface.php | 62 ++++++ .../CollectionPropertiesMutableAbstract.php | 72 +++++++ ... CollectionPropertiesMutableInterface.php} | 21 +- .../lib/Chrono/Collection/CollectionRoles.php | 23 -- .../lib/Chrono/Collection/ICollectionBase.php | 160 -------------- .../lib/Chrono/Entity/EntityBaseAbstract.php | 31 +++ .../lib/Chrono/Entity/EntityBaseInterface.php | 25 +++ .../Chrono/Entity/EntityMutableAbstract.php | 47 +++++ .../Chrono/Entity/EntityMutableInterface.php | 28 +++ .../lib/Chrono/Entity/EntityPermissions.php | 25 --- .../Entity/EntityPropertiesBaseAbstract.php | 21 ++ .../Entity/EntityPropertiesBaseInterface.php | 21 ++ .../EntityPropertiesMutableAbstract.php | 30 +++ .../EntityPropertiesMutableInterface.php | 20 ++ shared/lib/Chrono/Entity/IEntityBase.php | 93 -------- shared/lib/Chrono/Entity/IEntityMutable.php | 51 ----- shared/lib/Chrono/Provider/IProviderBase.php | 96 --------- .../Provider/IProviderServiceMutate.php | 50 ----- .../Chrono/Provider/ProviderBaseInterface.php | 23 ++ .../ProviderServiceMutateInterface.php | 35 ++++ .../Provider/ProviderServiceTestInterface.php | 57 +++++ shared/lib/Chrono/Service/IServiceBase.php | 197 ----------------- .../Service/IServiceCollectionMutable.php | 79 ------- .../Chrono/Service/IServiceEntityMutable.php | 81 ------- shared/lib/Chrono/Service/IServiceMutable.php | 30 --- .../Chrono/Service/ServiceBaseInterface.php | 198 ++++++++++++++++++ .../ServiceCollectionMutableInterface.php | 73 +++++++ .../Service/ServiceConfigurableInterface.php | 26 +++ .../Service/ServiceEntityMutableInterface.php | 77 +++++++ .../Service/ServiceMutableInterface.php | 22 ++ .../Provider/ResourceServiceBaseInterface.php | 4 +- 37 files changed, 1097 insertions(+), 926 deletions(-) create mode 100644 shared/lib/Chrono/Collection/CollectionBaseAbstract.php create mode 100644 shared/lib/Chrono/Collection/CollectionBaseInterface.php create mode 100644 shared/lib/Chrono/Collection/CollectionMutableAbstract.php create mode 100644 shared/lib/Chrono/Collection/CollectionMutableInterface.php delete mode 100644 shared/lib/Chrono/Collection/CollectionPermissions.php create mode 100644 shared/lib/Chrono/Collection/CollectionPropertiesBaseAbstract.php create mode 100644 shared/lib/Chrono/Collection/CollectionPropertiesBaseInterface.php create mode 100644 shared/lib/Chrono/Collection/CollectionPropertiesMutableAbstract.php rename shared/lib/Chrono/Collection/{ICollectionMutable.php => CollectionPropertiesMutableInterface.php} (55%) delete mode 100644 shared/lib/Chrono/Collection/CollectionRoles.php delete mode 100644 shared/lib/Chrono/Collection/ICollectionBase.php create mode 100644 shared/lib/Chrono/Entity/EntityBaseAbstract.php create mode 100644 shared/lib/Chrono/Entity/EntityBaseInterface.php create mode 100644 shared/lib/Chrono/Entity/EntityMutableAbstract.php create mode 100644 shared/lib/Chrono/Entity/EntityMutableInterface.php delete mode 100644 shared/lib/Chrono/Entity/EntityPermissions.php create mode 100644 shared/lib/Chrono/Entity/EntityPropertiesBaseAbstract.php create mode 100644 shared/lib/Chrono/Entity/EntityPropertiesBaseInterface.php create mode 100644 shared/lib/Chrono/Entity/EntityPropertiesMutableAbstract.php create mode 100644 shared/lib/Chrono/Entity/EntityPropertiesMutableInterface.php delete mode 100644 shared/lib/Chrono/Entity/IEntityBase.php delete mode 100644 shared/lib/Chrono/Entity/IEntityMutable.php delete mode 100644 shared/lib/Chrono/Provider/IProviderBase.php delete mode 100644 shared/lib/Chrono/Provider/IProviderServiceMutate.php create mode 100644 shared/lib/Chrono/Provider/ProviderBaseInterface.php create mode 100644 shared/lib/Chrono/Provider/ProviderServiceMutateInterface.php create mode 100644 shared/lib/Chrono/Provider/ProviderServiceTestInterface.php delete mode 100644 shared/lib/Chrono/Service/IServiceBase.php delete mode 100644 shared/lib/Chrono/Service/IServiceCollectionMutable.php delete mode 100644 shared/lib/Chrono/Service/IServiceEntityMutable.php delete mode 100644 shared/lib/Chrono/Service/IServiceMutable.php create mode 100644 shared/lib/Chrono/Service/ServiceBaseInterface.php create mode 100644 shared/lib/Chrono/Service/ServiceCollectionMutableInterface.php create mode 100644 shared/lib/Chrono/Service/ServiceConfigurableInterface.php create mode 100644 shared/lib/Chrono/Service/ServiceEntityMutableInterface.php create mode 100644 shared/lib/Chrono/Service/ServiceMutableInterface.php diff --git a/shared/lib/Chrono/Collection/CollectionBaseAbstract.php b/shared/lib/Chrono/Collection/CollectionBaseAbstract.php new file mode 100644 index 0000000..ea5b82e --- /dev/null +++ b/shared/lib/Chrono/Collection/CollectionBaseAbstract.php @@ -0,0 +1,31 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Collection; + +use KTXF\Resource\Provider\Node\NodeBaseAbstract; + +/** + * Abstract Chrono Collection Base Class + * + * Provides common implementation for chrono collections + * + * @since 2025.05.01 + */ +abstract class CollectionBase extends NodeBaseAbstract implements CollectionBaseInterface { + + protected CollectionPropertiesBaseAbstract $properties; + + /** + * @inheritDoc + */ + public function getProperties(): CollectionPropertiesBaseInterface { + return $this->properties; + } +} diff --git a/shared/lib/Chrono/Collection/CollectionBaseInterface.php b/shared/lib/Chrono/Collection/CollectionBaseInterface.php new file mode 100644 index 0000000..5ceb6e8 --- /dev/null +++ b/shared/lib/Chrono/Collection/CollectionBaseInterface.php @@ -0,0 +1,30 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Collection; + +use KTXF\Resource\Provider\Node\NodeBaseInterface; + +/** + * Chrono Collection Base Interface + * + * Interface represents a collection in a chrono service + * + * @since 2025.05.01 + */ +interface CollectionBaseInterface extends NodeBaseInterface { + + /** + * Gets the collection properties + * + * @since 2025.05.01 + */ + public function getProperties(): CollectionPropertiesBaseInterface|CollectionPropertiesMutableInterface; + +} diff --git a/shared/lib/Chrono/Collection/CollectionMutableAbstract.php b/shared/lib/Chrono/Collection/CollectionMutableAbstract.php new file mode 100644 index 0000000..77d3ac1 --- /dev/null +++ b/shared/lib/Chrono/Collection/CollectionMutableAbstract.php @@ -0,0 +1,50 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Collection; + +use KTXF\Resource\Provider\Node\NodeMutableAbstract; +use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface; + +/** + * Abstract Chrono Collection Mutable Class + * + * Provides common implementation for mutable chrono collections + * + * @since 2025.05.01 + */ +abstract class CollectionMutableAbstract extends NodeMutableAbstract implements CollectionMutableInterface { + + protected CollectionPropertiesMutableAbstract $properties; + + /** + * @inheritDoc + */ + public function getProperties(): CollectionPropertiesMutableInterface { + return $this->properties; + } + + /** + * @inheritDoc + */ + public function setProperties(NodePropertiesMutableInterface $value): static { + if (!$value instanceof CollectionPropertiesMutableInterface) { + throw new \InvalidArgumentException('Properties must implement CollectionPropertiesMutableInterface'); + } + + // Copy all property values + $this->properties->setLabel($value->getLabel()); + $this->properties->setDescription($value->getDescription()); + $this->properties->setPriority($value->getPriority()); + $this->properties->setVisibility($value->getVisibility()); + $this->properties->setColor($value->getColor()); + + return $this; + } +} diff --git a/shared/lib/Chrono/Collection/CollectionMutableInterface.php b/shared/lib/Chrono/Collection/CollectionMutableInterface.php new file mode 100644 index 0000000..4601934 --- /dev/null +++ b/shared/lib/Chrono/Collection/CollectionMutableInterface.php @@ -0,0 +1,32 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Collection; + +use KTXF\Resource\Provider\Node\NodeMutableInterface; + +/** + * Chrono Collection Mutable Interface + * + * Interface for altering collection properties in a chrono service + * + * @since 2025.05.01 + * + * @method static setProperties(CollectionPropertiesMutableInterface $value) + */ +interface CollectionMutableInterface extends CollectionBaseInterface, NodeMutableInterface { + + /** + * Gets the collection properties (mutable) + * + * @since 2025.05.01 + */ + public function getProperties(): CollectionPropertiesMutableInterface; + +} diff --git a/shared/lib/Chrono/Collection/CollectionPermissions.php b/shared/lib/Chrono/Collection/CollectionPermissions.php deleted file mode 100644 index 8c11f26..0000000 --- a/shared/lib/Chrono/Collection/CollectionPermissions.php +++ /dev/null @@ -1,26 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Collection; - -use JsonSerializable; - -enum CollectionPermissions: string implements JsonSerializable { - - case View = 'view'; - case Create = 'create'; - case Modify = 'modify'; - case Destroy = 'destroy'; - case Share = 'share'; - - public function jsonSerialize(): string { - return $this->value; - } - -} diff --git a/shared/lib/Chrono/Collection/CollectionPropertiesBaseAbstract.php b/shared/lib/Chrono/Collection/CollectionPropertiesBaseAbstract.php new file mode 100644 index 0000000..178503d --- /dev/null +++ b/shared/lib/Chrono/Collection/CollectionPropertiesBaseAbstract.php @@ -0,0 +1,76 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Collection; + +use KTXF\Resource\Provider\Node\NodePropertiesBaseAbstract; + +/** + * Abstract Chrono Collection Properties Base Class + * + * Provides common implementation for chrono collection properties + * + * @since 2025.05.01 + */ +abstract class CollectionPropertiesBaseAbstract extends NodePropertiesBaseAbstract implements CollectionPropertiesBaseInterface { + + public const JSON_TYPE = CollectionPropertiesBaseInterface::JSON_TYPE; + + /** + * @inheritDoc + */ + public function content(): CollectionContent { + $content = $this->data[self::JSON_PROPERTY_CONTENTS] ?? null; + if ($content instanceof CollectionContent) { + return $content; + } + + if (is_string($content)) { + return CollectionContent::tryFrom($content) ?? CollectionContent::Event; + } + + return CollectionContent::Event; + } + + /** + * @inheritDoc + */ + public function getLabel(): string { + return $this->data[self::JSON_PROPERTY_LABEL] ?? ''; + } + + /** + * @inheritDoc + */ + public function getDescription(): ?string { + return $this->data[self::JSON_PROPERTY_DESCRIPTION] ?? null; + } + + /** + * @inheritDoc + */ + public function getPriority(): ?int { + return $this->data[self::JSON_PROPERTY_PRIORITY] ?? null; + } + + /** + * @inheritDoc + */ + public function getVisibility(): ?bool { + return $this->data[self::JSON_PROPERTY_VISIBILITY] ?? null; + } + + /** + * @inheritDoc + */ + public function getColor(): ?string { + return $this->data[self::JSON_PROPERTY_COLOR] ?? null; + } + +} diff --git a/shared/lib/Chrono/Collection/CollectionPropertiesBaseInterface.php b/shared/lib/Chrono/Collection/CollectionPropertiesBaseInterface.php new file mode 100644 index 0000000..249999a --- /dev/null +++ b/shared/lib/Chrono/Collection/CollectionPropertiesBaseInterface.php @@ -0,0 +1,62 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Collection; + +use KTXF\Resource\Provider\Node\NodePropertiesBaseInterface; + +interface CollectionPropertiesBaseInterface extends NodePropertiesBaseInterface { + + public const JSON_TYPE = 'chrono.collection'; + public const JSON_PROPERTY_CONTENTS = 'content'; + + public const JSON_PROPERTY_LABEL = 'label'; + public const JSON_PROPERTY_DESCRIPTION = 'description'; + public const JSON_PROPERTY_PRIORITY = 'priority'; + public const JSON_PROPERTY_VISIBILITY = 'visibility'; + public const JSON_PROPERTY_COLOR = 'color'; + + public function content(): CollectionContent; + + /** + * Gets the human friendly name of this collection (e.g. Personal Calendar) + * + * @since 2025.05.01 + */ + public function getLabel(): string; + + /** + * Gets the human friendly description of this collection + * + * @since 2025.05.01 + */ + public function getDescription(): ?string; + + /** + * Gets the priority of this collection + * + * @since 2025.05.01 + */ + public function getPriority(): ?int; + + /** + * Gets the visibility of this collection + * + * @since 2025.05.01 + */ + public function getVisibility(): ?bool; + + /** + * Gets the color of this collection + * + * @since 2025.05.01 + */ + public function getColor(): ?string; + +} diff --git a/shared/lib/Chrono/Collection/CollectionPropertiesMutableAbstract.php b/shared/lib/Chrono/Collection/CollectionPropertiesMutableAbstract.php new file mode 100644 index 0000000..d3cfc23 --- /dev/null +++ b/shared/lib/Chrono/Collection/CollectionPropertiesMutableAbstract.php @@ -0,0 +1,72 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Collection; + +/** + * Abstract Chrono Collection Properties Mutable Class + */ +abstract class CollectionPropertiesMutableAbstract extends CollectionPropertiesBaseAbstract implements CollectionPropertiesMutableInterface { + + public const JSON_TYPE = CollectionPropertiesBaseInterface::JSON_TYPE; + + /** + * @inheritDoc + */ + public function jsonDeserialize(array|string $data): static { + if (is_string($data)) { + $data = json_decode($data, true); + } + + $this->data = $data; + + return $this; + } + + /** + * @inheritDoc + */ + public function setLabel(string $value): static { + $this->data[self::JSON_PROPERTY_LABEL] = $value; + return $this; + } + + /** + * @inheritDoc + */ + public function setDescription(?string $value): static { + $this->data[self::JSON_PROPERTY_DESCRIPTION] = $value; + return $this; + } + + /** + * @inheritDoc + */ + public function setPriority(?int $value): static { + $this->data[self::JSON_PROPERTY_PRIORITY] = $value; + return $this; + } + + /** + * @inheritDoc + */ + public function setVisibility(?bool $value): static { + $this->data[self::JSON_PROPERTY_VISIBILITY] = $value; + return $this; + } + + /** + * @inheritDoc + */ + public function setColor(?string $value): static { + $this->data[self::JSON_PROPERTY_COLOR] = $value; + return $this; + } + +} diff --git a/shared/lib/Chrono/Collection/ICollectionMutable.php b/shared/lib/Chrono/Collection/CollectionPropertiesMutableInterface.php similarity index 55% rename from shared/lib/Chrono/Collection/ICollectionMutable.php rename to shared/lib/Chrono/Collection/CollectionPropertiesMutableInterface.php index 167f02c..2fc9314 100644 --- a/shared/lib/Chrono/Collection/ICollectionMutable.php +++ b/shared/lib/Chrono/Collection/CollectionPropertiesMutableInterface.php @@ -9,50 +9,45 @@ declare(strict_types=1); namespace KTXF\Chrono\Collection; -use KTXF\Json\JsonDeserializable; +use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface; -interface ICollectionMutable extends ICollectionBase, JsonDeserializable { +interface CollectionPropertiesMutableInterface extends CollectionPropertiesBaseInterface, NodePropertiesMutableInterface { - /** - * Sets the active status of this collection - * - * @since 2025.05.01 - */ - public function setEnabled(bool $value): self; + public const JSON_TYPE = CollectionPropertiesBaseInterface::JSON_TYPE; /** * Sets the human friendly name of this collection (e.g. Personal Calendar) * * @since 2025.05.01 */ - public function setLabel(string $value): self; + public function setLabel(string $value): static; /** * Sets the human friendly description of this collection * * @since 2025.05.01 */ - public function setDescription(?string $value): self; + public function setDescription(?string $value): static; /** * Sets the priority of this collection * * @since 2025.05.01 */ - public function setPriority(?int $value): self; + public function setPriority(?int $value): static; /** * Sets the visibility of this collection * * @since 2025.05.01 */ - public function setVisibility(?bool $value): self; + public function setVisibility(?bool $value): static; /** * Sets the color of this collection * * @since 2025.05.01 */ - public function setColor(?string $value): self; + public function setColor(?string $value): static; } diff --git a/shared/lib/Chrono/Collection/CollectionRoles.php b/shared/lib/Chrono/Collection/CollectionRoles.php deleted file mode 100644 index 602c2c5..0000000 --- a/shared/lib/Chrono/Collection/CollectionRoles.php +++ /dev/null @@ -1,23 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Collection; - -use JsonSerializable; - -enum CollectionRoles: string implements JsonSerializable { - - case System = 'system'; - case Individual = 'individual'; - - public function jsonSerialize(): string { - return $this->value; - } - -} diff --git a/shared/lib/Chrono/Collection/ICollectionBase.php b/shared/lib/Chrono/Collection/ICollectionBase.php deleted file mode 100644 index cb5e438..0000000 --- a/shared/lib/Chrono/Collection/ICollectionBase.php +++ /dev/null @@ -1,160 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Collection; - -use DateTimeImmutable; -use JsonSerializable; - -interface ICollectionBase extends JsonSerializable { - - public const JSON_TYPE = 'chrono.collection'; - public const JSON_PROPERTY_TYPE = '@type'; - public const JSON_PROPERTY_PROVIDER = 'provider'; - public const JSON_PROPERTY_SERVICE = 'service'; - public const JSON_PROPERTY_IN = 'in'; - public const JSON_PROPERTY_ID = 'id'; - public const JSON_PROPERTY_LABEL = 'label'; - public const JSON_PROPERTY_DESCRIPTION = 'description'; - public const JSON_PROPERTY_PRIORITY = 'priority'; - public const JSON_PROPERTY_VISIBILITY = 'visibility'; - public const JSON_PROPERTY_COLOR = 'color'; - public const JSON_PROPERTY_CREATED = 'created'; - public const JSON_PROPERTY_MODIFIED = 'modified'; - public const JSON_PROPERTY_ENABLED = 'enabled'; - public const JSON_PROPERTY_SIGNATURE = 'signature'; - public const JSON_PROPERTY_PERMISSIONS = 'permissions'; - public const JSON_PROPERTY_ROLES = 'roles'; - public const JSON_PROPERTY_CONTENTS = 'contents'; - - /** - * Unique identifier of the service this collection belongs to - * - * @since 2025.05.01 - */ - public function in(): string|int|null; - - /** - * Unique arbitrary text string identifying this collection (e.g. 1 or collection1 or anything else) - * - * @since 2025.05.01 - */ - public function id(): string|int; - - /** - * Gets the creation date of this collection - */ - public function created(): ?DateTimeImmutable; - - /** - * Gets the modification date of this collection - */ - public function modified(): ?DateTimeImmutable; - - /** - * Lists all supported attributes - * - * @since 2025.05.01 - * - * @return array> - */ - public function attributes(): array; - - /** - * Gets the signature of this collection - * - * @since 2025.05.01 - */ - public function signature(): ?string; - - /** - * Gets the role(s) of this collection - * - * @since 2025.05.01 - */ - public function roles(): array; - - /** - * Checks if this collection supports the given role - * - * @since 2025.05.01 - */ - public function role(CollectionRoles $value): bool; - - /** - * Gets the content types of this collection - * - * @since 2025.05.01 - */ - public function contents(): array; - - /** - * Checks if this collection contains the given content type - * - * @since 2025.05.01 - */ - public function contains(CollectionContent $value): bool; - - /** - * Gets the active status of this collection - * - * @since 2025.05.01 - */ - public function getEnabled(): bool; - - /** - * Gets the permissions of this collection - * - * @since 2025.05.01 - */ - public function getPermissions(): array; - - /** - * Checks if this collection has the given permission - * - * @since 2025.05.01 - */ - public function hasPermission(CollectionPermissions $permission): bool; - - /** - * Gets the human friendly name of this collection (e.g. Personal Calendar) - * - * @since 2025.05.01 - */ - public function getLabel(): ?string; - - /** - * Gets the human friendly description of this collection - * - * @since 2025.05.01 - */ - public function getDescription(): ?string; - - /** - * Gets the priority of this collection - * - * @since 2025.05.01 - */ - public function getPriority(): ?int; - - /** - * Gets the visibility of this collection - * - * @since 2025.05.01 - */ - public function getVisibility(): ?bool; - - /** - * Gets the color of this collection - * - * @since 2025.05.01 - */ - public function getColor(): ?string; - -} diff --git a/shared/lib/Chrono/Entity/EntityBaseAbstract.php b/shared/lib/Chrono/Entity/EntityBaseAbstract.php new file mode 100644 index 0000000..e94da59 --- /dev/null +++ b/shared/lib/Chrono/Entity/EntityBaseAbstract.php @@ -0,0 +1,31 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Entity; + +use KTXF\Resource\Provider\Node\NodeBaseAbstract; + +/** + * Abstract Chrono Entity Base Class + * + * Provides common implementation for chrono entities + * + * @since 2025.05.01 + */ +abstract class EntityBaseAbstract extends NodeBaseAbstract implements EntityBaseInterface { + + protected EntityPropertiesBaseAbstract $properties; + + /** + * @inheritDoc + */ + public function getProperties(): EntityPropertiesBaseInterface { + return $this->properties; + } +} diff --git a/shared/lib/Chrono/Entity/EntityBaseInterface.php b/shared/lib/Chrono/Entity/EntityBaseInterface.php new file mode 100644 index 0000000..afeedf3 --- /dev/null +++ b/shared/lib/Chrono/Entity/EntityBaseInterface.php @@ -0,0 +1,25 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Entity; + +use KTXF\Resource\Provider\Node\NodeBaseInterface; + +interface EntityBaseInterface extends NodeBaseInterface { + + public const JSON_TYPE = 'chrono.entity'; + + /** + * Gets the entity properties + * + * @since 2025.05.01 + */ + public function getProperties(): EntityPropertiesBaseInterface|EntityPropertiesMutableInterface; + +} diff --git a/shared/lib/Chrono/Entity/EntityMutableAbstract.php b/shared/lib/Chrono/Entity/EntityMutableAbstract.php new file mode 100644 index 0000000..77af5af --- /dev/null +++ b/shared/lib/Chrono/Entity/EntityMutableAbstract.php @@ -0,0 +1,47 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Entity; + +use KTXF\Resource\Provider\Node\NodeMutableAbstract; +use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface; + +/** + * Abstract Chrono Entity Mutable Class + * + * Provides common implementation for mutable chrono entities + * + * @since 2025.05.01 + */ +abstract class EntityMutableAbstract extends NodeMutableAbstract implements EntityMutableInterface { + + public const JSON_TYPE = EntityMutableInterface::JSON_TYPE; + + protected EntityPropertiesMutableAbstract $properties; + + /** + * @inheritDoc + */ + public function getProperties(): EntityPropertiesMutableInterface { + return $this->properties; + } + + /** + * @inheritDoc + */ + public function setProperties(NodePropertiesMutableInterface $value): static { + if (!$value instanceof EntityPropertiesMutableInterface) { + throw new \InvalidArgumentException('Properties must implement EntityPropertiesMutableInterface'); + } + + $this->properties->setDataRaw($value->getDataRaw()); + + return $this; + } +} diff --git a/shared/lib/Chrono/Entity/EntityMutableInterface.php b/shared/lib/Chrono/Entity/EntityMutableInterface.php new file mode 100644 index 0000000..cf6f2d1 --- /dev/null +++ b/shared/lib/Chrono/Entity/EntityMutableInterface.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Entity; + +use KTXF\Resource\Provider\Node\NodeMutableInterface; + +/** + * @method static setProperties(EntityPropertiesMutableInterface $value) + */ +interface EntityMutableInterface extends EntityBaseInterface, NodeMutableInterface { + + public const JSON_TYPE = EntityBaseInterface::JSON_TYPE; + + /** + * Gets the entity properties (mutable) + * + * @since 2025.05.01 + */ + public function getProperties(): EntityPropertiesMutableInterface; + +} diff --git a/shared/lib/Chrono/Entity/EntityPermissions.php b/shared/lib/Chrono/Entity/EntityPermissions.php deleted file mode 100644 index fd77959..0000000 --- a/shared/lib/Chrono/Entity/EntityPermissions.php +++ /dev/null @@ -1,25 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Entity; - -use JsonSerializable; - -enum EntityPermissions: string implements JsonSerializable { - - case View = 'view'; - case Modify = 'modify'; - case Delete = 'delete'; - case Share = 'share'; - - public function jsonSerialize(): string { - return $this->value; - } - -} diff --git a/shared/lib/Chrono/Entity/EntityPropertiesBaseAbstract.php b/shared/lib/Chrono/Entity/EntityPropertiesBaseAbstract.php new file mode 100644 index 0000000..6b6d646 --- /dev/null +++ b/shared/lib/Chrono/Entity/EntityPropertiesBaseAbstract.php @@ -0,0 +1,21 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Entity; + +use KTXF\Resource\Provider\Node\NodePropertiesBaseAbstract; + +abstract class EntityPropertiesBaseAbstract extends NodePropertiesBaseAbstract implements EntityPropertiesBaseInterface { + + public const JSON_TYPE = EntityPropertiesBaseInterface::JSON_TYPE; + + public function getDataRaw(): array|string|null { + return $this->data[self::JSON_PROPERTY_DATA] ?? null; + } +} diff --git a/shared/lib/Chrono/Entity/EntityPropertiesBaseInterface.php b/shared/lib/Chrono/Entity/EntityPropertiesBaseInterface.php new file mode 100644 index 0000000..2ea578d --- /dev/null +++ b/shared/lib/Chrono/Entity/EntityPropertiesBaseInterface.php @@ -0,0 +1,21 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Entity; + +use KTXF\Resource\Provider\Node\NodePropertiesBaseInterface; + +interface EntityPropertiesBaseInterface extends NodePropertiesBaseInterface { + + public const JSON_TYPE = 'chrono.entity'; + public const JSON_PROPERTY_DATA = 'data'; + + public function getDataRaw(): array|string|null; + +} diff --git a/shared/lib/Chrono/Entity/EntityPropertiesMutableAbstract.php b/shared/lib/Chrono/Entity/EntityPropertiesMutableAbstract.php new file mode 100644 index 0000000..3917f4f --- /dev/null +++ b/shared/lib/Chrono/Entity/EntityPropertiesMutableAbstract.php @@ -0,0 +1,30 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Entity; + +abstract class EntityPropertiesMutableAbstract extends EntityPropertiesBaseAbstract implements EntityPropertiesMutableInterface { + + public const JSON_TYPE = EntityPropertiesBaseInterface::JSON_TYPE; + + public function jsonDeserialize(array|string $data): static { + if (is_string($data)) { + $data = json_decode($data, true); + } + + $this->data = $data; + + return $this; + } + + public function setDataRaw(array|string|null $value): static { + $this->data[self::JSON_PROPERTY_DATA] = $value; + return $this; + } +} diff --git a/shared/lib/Chrono/Entity/EntityPropertiesMutableInterface.php b/shared/lib/Chrono/Entity/EntityPropertiesMutableInterface.php new file mode 100644 index 0000000..ebb3d2c --- /dev/null +++ b/shared/lib/Chrono/Entity/EntityPropertiesMutableInterface.php @@ -0,0 +1,20 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Entity; + +use KTXF\Resource\Provider\Node\NodePropertiesMutableInterface; + +interface EntityPropertiesMutableInterface extends EntityPropertiesBaseInterface, NodePropertiesMutableInterface { + + public const JSON_TYPE = EntityPropertiesBaseInterface::JSON_TYPE; + + public function setDataRaw(array|string|null $value): static; + +} diff --git a/shared/lib/Chrono/Entity/IEntityBase.php b/shared/lib/Chrono/Entity/IEntityBase.php deleted file mode 100644 index d3cf50c..0000000 --- a/shared/lib/Chrono/Entity/IEntityBase.php +++ /dev/null @@ -1,93 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Entity; - -use DateTimeImmutable; - -interface IEntityBase extends \JsonSerializable { - - public const JSON_TYPE = 'chrono.entity'; - public const JSON_PROPERTY_TYPE = '@type'; - public const JSON_PROPERTY_IN = 'in'; - public const JSON_PROPERTY_ID = 'id'; - public const JSON_PROPERTY_DATA = 'data'; - public const JSON_PROPERTY_CREATED = 'created'; - public const JSON_PROPERTY_MODIFIED = 'modified'; - public const JSON_PROPERTY_SIGNATURE = 'signature'; - - /** - * Unique arbitrary text string identifying the collection this entity belongs to (e.g. 1 or Collection1 or anything else) - * - * @since 2025.05.01 - */ - public function in(): string|int; - - /** - * Unique arbitrary text string identifying this entity (e.g. 1 or Entity or anything else) - * - * @since 2025.05.01 - */ - public function id(): string|int; - - /** - * Gets the creation date of this entity - */ - public function created(): ?DateTimeImmutable; - - /** - * Gets the modification date of this entity - */ - public function modified(): ?DateTimeImmutable; - - /** - * Gets the signature of this entity - * - * @since 2025.05.01 - */ - public function signature(): ?string; - - /** - * Gets the priority of this entity - * - * @since 2025.05.01 - */ - public function getPriority(): ?int; - - /** - * Gets the visibility of this entity - * - * @since 2025.05.01 - */ - public function getVisibility(): ?bool; - - /** - * Gets the color of this entity - * - * @since 2025.05.01 - */ - public function getColor(): ?string; - - /** - * Gets the object data (event, task, or journal). - * - * @since 2025.05.01 - */ - public function getDataObject(): object|null; - - /** - * Gets the raw data as an associative array or JSON string. - * - * @since 2025.05.01 - * - * @return array|string|null - */ - public function getDataJson(): array|string|null; - -} diff --git a/shared/lib/Chrono/Entity/IEntityMutable.php b/shared/lib/Chrono/Entity/IEntityMutable.php deleted file mode 100644 index 244d313..0000000 --- a/shared/lib/Chrono/Entity/IEntityMutable.php +++ /dev/null @@ -1,51 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Entity; - -use KTXF\Json\JsonDeserializable; - -interface IEntityMutable extends IEntityBase, JsonDeserializable { - - /** - * Sets the priority of this entity - * - * @since 2025.05.01 - */ - public function setPriority(?int $value): static; - - /** - * Sets the visibility of this entity - * - * @since 2025.05.01 - */ - public function setVisibility(?bool $value): static; - - /** - * Sets the color of this entity - * - * @since 2025.05.01 - */ - public function setColor(?string $value): static; - - /** - * Sets the object as a class instance. - * - * @since 2025.05.01 - */ - public function setDataObject(object $value): static; - - /** - * Sets the object data from a json string - * - * @since 2025.05.01 - */ - public function setDataJson(array|string $value): static; - -} diff --git a/shared/lib/Chrono/Provider/IProviderBase.php b/shared/lib/Chrono/Provider/IProviderBase.php deleted file mode 100644 index d65d3d9..0000000 --- a/shared/lib/Chrono/Provider/IProviderBase.php +++ /dev/null @@ -1,96 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Provider; - -use JsonSerializable; -use KTXF\Chrono\Service\IServiceBase; - -interface IProviderBase extends JsonSerializable { - - public const CAPABILITY_SERVICE_LIST = 'ServiceList'; - public const CAPABILITY_SERVICE_FETCH = 'ServiceFetch'; - public const CAPABILITY_SERVICE_EXTANT = 'ServiceExtant'; - - public const JSON_TYPE = 'chrono.provider'; - public const JSON_PROPERTY_TYPE = '@type'; - public const JSON_PROPERTY_ID = 'id'; - public const JSON_PROPERTY_LABEL = 'label'; - public const JSON_PROPERTY_CAPABILITIES = 'capabilities'; - - /** - * Confirms if specific capability is supported (e.g. 'ServiceList') - * - * @since 2025.05.01 - */ - public function capable(string $value): bool; - - /** - * Lists all supported capabilities - * - * @since 2025.05.01 - * - * @return array - */ - public function capabilities(): array; - - /** - * An arbitrary unique text string identifying this provider (e.g. UUID or 'system' or anything else) - * - * @since 2025.05.01 - */ - public function id(): string; - - /** - * The localized human friendly name of this provider (e.g. System Calendar Provider) - * - * @since 2025.05.01 - */ - public function label(): string; - - /** - * Retrieve collection of services for a specific user - * - * @since 2025.05.01 - * - * @param string $tenantId tenant identifier - * @param string $userId user identifier - * @param array $filter filter criteria - * - * @return array collection of service objects - */ - public function serviceList(string $tenantId, string $userId, array $filter): array; - - /** - * Determine if any services are configured for a specific user - * - * @since 2025.05.01 - * - * @param string $tenantId tenant identifier - * @param string $userId user identifier - * @param int|string ...$identifiers variadic collection of service identifiers - * - * @return array collection of service identifiers with boolean values indicating if the service is available - */ - public function serviceExtant(string $tenantId, string $userId, int|string ...$identifiers): array; - - /** - * Retrieve a service with a specific identifier - * - * @since 2025.05.01 - * - * @param string $tenantId tenant identifier - * @param string $userId user identifier - * @param string|int $identifier service identifier - * - * @return IServiceBase|null returns service object or null if non found - */ - public function serviceFetch(string $tenantId, string $userId, string|int $identifier): ?IServiceBase; - -} diff --git a/shared/lib/Chrono/Provider/IProviderServiceMutate.php b/shared/lib/Chrono/Provider/IProviderServiceMutate.php deleted file mode 100644 index 6a90e27..0000000 --- a/shared/lib/Chrono/Provider/IProviderServiceMutate.php +++ /dev/null @@ -1,50 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Provider; - -use KTXF\Json\JsonDeserializable; -use KTXF\Chrono\Service\IServiceBase; - -interface IProviderServiceMutate extends JsonDeserializable { - - public const CAPABILITY_SERVICE_FRESH = 'ServiceFresh'; - public const CAPABILITY_SERVICE_CREATE = 'ServiceCreate'; - public const CAPABILITY_SERVICE_UPDATE = 'ServiceUpdate'; - public const CAPABILITY_SERVICE_DESTROY = 'ServiceDestroy'; - - /** - * construct and new blank service instance - * - * @since 2025.05.01 - */ - public function serviceFresh(string $uid = ''): IServiceBase; - - /** - * create a service configuration for a specific user - * - * @since 2025.05.01 - */ - public function serviceCreate(string $uid, IServiceBase $service): string; - - /** - * modify a service configuration for a specific user - * - * @since 2025.05.01 - */ - public function serviceModify(string $uid, IServiceBase $service): string; - - /** - * delete a service configuration for a specific user - * - * @since 2025.05.01 - */ - public function serviceDestroy(string $uid, IServiceBase $service): bool; - -} diff --git a/shared/lib/Chrono/Provider/ProviderBaseInterface.php b/shared/lib/Chrono/Provider/ProviderBaseInterface.php new file mode 100644 index 0000000..c10a531 --- /dev/null +++ b/shared/lib/Chrono/Provider/ProviderBaseInterface.php @@ -0,0 +1,23 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Provider; + +use KTXF\Resource\Provider\ResourceProviderBaseInterface; + +/** + * Chrono Provider Base Interface + * + * @since 2025.05.01 + */ +interface ProviderBaseInterface extends ResourceProviderBaseInterface{ + + public const JSON_TYPE = 'chrono.provider'; + +} diff --git a/shared/lib/Chrono/Provider/ProviderServiceMutateInterface.php b/shared/lib/Chrono/Provider/ProviderServiceMutateInterface.php new file mode 100644 index 0000000..8de64e6 --- /dev/null +++ b/shared/lib/Chrono/Provider/ProviderServiceMutateInterface.php @@ -0,0 +1,35 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Provider; + +use KTXF\Resource\Provider\ResourceProviderServiceMutateInterface; + +/** + * Chrono Provider Service Mutate Interface + * + * Optional interface for providers that support service CRUD operations. + * + * Implementations return ServiceMutableInterface instances (which extend ResourceServiceMutateInterface). + * + * @since 2025.05.01 + * + * @method ServiceMutableInterface serviceFresh() Construct a new blank chrono service instance + * @method string serviceCreate(string $tenantId, ?string $userId, ServiceMutableInterface $service) Create a chrono service configuration + * @method string serviceModify(string $tenantId, ?string $userId, ServiceMutableInterface $service) Modify a chrono service configuration + * @method bool serviceDestroy(string $tenantId, ?string $userId, ServiceMutableInterface $service) Delete a chrono service configuration + */ +interface ProviderServiceMutateInterface extends ProviderBaseInterface, ResourceProviderServiceMutateInterface { + + public const JSON_TYPE = ProviderBaseInterface::JSON_TYPE; + + // Methods inherited from ResourceProviderServiceMutateInterface + // Implementations should return/accept ServiceMutableInterface instances + +} diff --git a/shared/lib/Chrono/Provider/ProviderServiceTestInterface.php b/shared/lib/Chrono/Provider/ProviderServiceTestInterface.php new file mode 100644 index 0000000..32c5d72 --- /dev/null +++ b/shared/lib/Chrono/Provider/ProviderServiceTestInterface.php @@ -0,0 +1,57 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Provider; + +use KTXF\Mail\Service\ServiceBaseInterface; + +/** + * Chrono Provider Service Test Interface + * + * Optional interface for chrono providers that support testing service connections. + * Providers implementing this interface can validate connection parameters, + * test authentication, and verify service availability before creating a + * persistent service configuration. + * + * Supports two testing modes: + * 1. Testing an existing service (validate current configuration) + * 2. Testing a fresh configuration (validate before saving) + * + * @since 2025.05.01 + */ +interface ProviderServiceTestInterface extends ProviderBaseInterface { + + /** + * Test a service connection + * + * Tests connectivity, authentication, and capabilities of a service. + * + * For new services: use serviceFresh() to create a service, configure it with + * setters, then pass it to this method for testing before persisting. + * + * For existing services: fetch the service and pass it directly. + * + * @since 2025.05.01 + * + * @param ServiceBaseInterface $service Service to test (can be fresh/unsaved or existing) + * @param array $options Provider-specific test options: + * - 'timeout' => int (seconds, default: 10) + * - 'verify_ssl' => bool (default: true) + * - 'test_send' => bool (attempt test send if capable, default: false) + * - 'test_receive' => bool (attempt mailbox access if capable, default: true) + * + * @return array Test results in the format: + * [ + * 'success' => bool, + * 'message' => 'Connection successful' | 'Error message' + * ] + */ + public function serviceTest(ServiceBaseInterface $service, array $options = []): array; + +} diff --git a/shared/lib/Chrono/Service/IServiceBase.php b/shared/lib/Chrono/Service/IServiceBase.php deleted file mode 100644 index 424fd4f..0000000 --- a/shared/lib/Chrono/Service/IServiceBase.php +++ /dev/null @@ -1,197 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Service; - -use JsonSerializable; -use KTXF\Chrono\Collection\ICollectionBase; -use KTXF\Resource\Filter\IFilter; -use KTXF\Resource\Range\IRange; -use KTXF\Resource\Range\RangeType; -use KTXF\Resource\Sort\ISort; - -interface IServiceBase extends JsonSerializable { - - public const CAPABILITY_COLLECTION_LIST = 'CollectionList'; - public const CAPABILITY_COLLECTION_LIST_FILTER = 'CollectionListFilter'; - public const CAPABILITY_COLLECTION_LIST_SORT = 'CollectionListSort'; - public const CAPABILITY_COLLECTION_EXTANT = 'CollectionExtant'; - public const CAPABILITY_COLLECTION_FETCH = 'CollectionFetch'; - - public const CAPABILITY_ENTITY_LIST = 'EntityList'; - public const CAPABILITY_ENTITY_LIST_FILTER = 'EntityListFilter'; - public const CAPABILITY_ENTITY_LIST_SORT = 'EntityListSort'; - public const CAPABILITY_ENTITY_LIST_RANGE = 'EntityListRange'; - public const CAPABILITY_ENTITY_DELTA = 'EntityDelta'; - public const CAPABILITY_ENTITY_EXTANT = 'EntityExtant'; - public const CAPABILITY_ENTITY_FETCH = 'EntityFetch'; - - public const CAPABILITY_FILTER_ANY = '*'; - public const CAPABILITY_FILTER_ID = 'id'; - public const CAPABILITY_FILTER_URID = 'urid'; - public const CAPABILITY_FILTER_LABEL = 'label'; - public const CAPABILITY_FILTER_DESCRIPTION = 'description'; - - public const CAPABILITY_SORT_ID = 'id'; - public const CAPABILITY_SORT_URID = 'urid'; - public const CAPABILITY_SORT_LABEL = 'label'; - public const CAPABILITY_SORT_PRIORITY = 'priority'; - - public const CAPABILITY_RANGE_TALLY = 'tally'; - public const CAPABILITY_RANGE_TALLY_ABSOLUTE = 'absolute'; - public const CAPABILITY_RANGE_TALLY_RELATIVE = 'relative'; - public const CAPABILITY_RANGE_DATE = 'date'; - - public const JSON_TYPE = 'chrono.service'; - public const JSON_PROPERTY_TYPE = '@type'; - public const JSON_PROPERTY_PROVIDER = 'provider'; - public const JSON_PROPERTY_ID = 'id'; - public const JSON_PROPERTY_LABEL = 'label'; - public const JSON_PROPERTY_CAPABILITIES = 'capabilities'; - public const JSON_PROPERTY_ENABLED = 'enabled'; - - /** - * Confirms if specific capability is supported - * - * @since 2025.05.01 - * - * @param string $value required ability e.g. 'EntityList' - * - * @return bool - */ - public function capable(string $value): bool; - - /** - * Lists all supported capabilities - * - * @since 2025.05.01 - * - * @return array - */ - public function capabilities(): array; - - /** - * Unique identifier of the provider this service belongs to - * - * @since 2025.05.01 - */ - public function in(): string; - - /** - * Unique arbitrary text string identifying this service (e.g. 1 or service1 or anything else) - * - * @since 2025.05.01 - */ - public function id(): string|int; - - /** - * Gets the localized human friendly name of this service (e.g. ACME Company Calendar Service) - * - * @since 2025.05.01 - */ - public function getLabel(): string; - - /** - * Gets the active status of this service - * - * @since 2025.05.01 - */ - public function getEnabled(): bool; - - /** - * Retrieve collection of collections for this service - * - * @since 2025.05.01 - */ - public function collectionList(?IFilter $filter = null, ?ISort $sort = null): array; - - /** - * Retrieve filter object for collection list - * - * @since 2025.05.01 - */ - public function collectionListFilter(): IFilter; - - /** - * Retrieve sort object for collection list - * - * @since 2025.05.01 - */ - public function collectionListSort(): ISort; - - /** - * Determine if a collection exists - * - * @since 2025.05.01 - */ - public function collectionExtant(string|int $identifier): bool; - - /** - * Retrieve a specific collection - * - * @since 2025.05.01 - */ - public function collectionFetch(string|int $identifier): ?ICollectionBase; - - /** - * Retrieve collection of entities from a specific collection - * - * @since 2025.05.01 - */ - public function entityList(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $elements = null): array; - - /** - * Retrieve filter object for entity list - * - * @since 2025.05.01 - */ - public function entityListFilter(): IFilter; - - /** - * Retrieve sort object for entity list - * - * @since 2025.05.01 - */ - public function entityListSort(): ISort; - - /** - * Retrieve range object for entity list - * - * @since 2025.05.01 - */ - public function entityListRange(RangeType $type): IRange; - - /** - * Retrieve collection of entities that have changed since a given signature - * - * @since 2025.05.01 - * - * @param string|int $collection collection identifier - * @param string $signature signature to compare against - * @param string $detail level of detail to return (ids, full, etc) - * - * @return array collection of entities or entity identifiers - */ - public function entityDelta(string|int $collection, string $signature, string $detail = 'ids'): array; - - /** - * Determine if entities exist in a specific collection - * - * @since 2025.05.01 - */ - public function entityExtant(string|int $collection, string|int ...$identifiers): array; - - /** - * Retrieve specific entities from a specific collection - * - * @since 2025.05.01 - */ - public function entityFetch(string|int $collection, string|int ...$identifiers): array; - -} diff --git a/shared/lib/Chrono/Service/IServiceCollectionMutable.php b/shared/lib/Chrono/Service/IServiceCollectionMutable.php deleted file mode 100644 index 78f6413..0000000 --- a/shared/lib/Chrono/Service/IServiceCollectionMutable.php +++ /dev/null @@ -1,79 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Service; - -use KTXF\Chrono\Collection\ICollectionBase; -use KTXF\Chrono\Collection\ICollectionMutable; - -interface IServiceCollectionMutable extends IServiceBase { - - public const CAPABILITY_COLLECTION_CREATE = 'CollectionCreate'; - public const CAPABILITY_COLLECTION_MODIFY = 'CollectionModify'; - public const CAPABILITY_COLLECTION_DESTROY = 'CollectionDestroy'; - public const CAPABILITY_COLLECTION_MOVE = 'CollectionMove'; - - /** - * Creates a new, empty collection object - * - * @since 2025.05.01 - * - * @return ICollectionMutable - */ - public function collectionFresh(): ICollectionMutable; - - /** - * Creates a new collection at the specified location - * - * @since 2025.05.01 - * - * @param string $location The parent collection to create this collection in, or empty string for root - * @param ICollectionMutable $collection The collection to create - * @param array $options Additional options for the collection creation - * - * @return ICollectionBase - * - * @throws \KTXF\Resource\Exceptions\InvalidArgumentException - * @throws \KTXF\Resource\Exceptions\UnsupportedException - * @throws \KTXF\Resource\Exceptions\UnauthorizedException - */ - public function collectionCreate(string|int $location, ICollectionMutable $collection, array $options): ICollectionBase; - - /** - * Modifies an existing collection - * - * @since 2025.05.01 - * - * @param string $identifier The ID of the collection to modify - * @param ICollectionMutable $collection The collection with modifications - * - * @return ICollectionBase - * - * @throws \KTXF\Resource\Exceptions\InvalidArgumentException - * @throws \KTXF\Resource\Exceptions\UnsupportedException - * @throws \KTXF\Resource\Exceptions\UnauthorizedException - */ - public function collectionModify(string|int $identifier, ICollectionMutable $collection): ICollectionBase; - - /** - * Destroys an existing collection - * - * @since 2025.05.01 - * - * @param string $identifier The ID of the collection to destroy - * - * @return bool - * - * @throws \KTXF\Resource\Exceptions\InvalidArgumentException - * @throws \KTXF\Resource\Exceptions\UnsupportedException - * @throws \KTXF\Resource\Exceptions\UnauthorizedException - */ - public function collectionDestroy(string|int $identifier): bool; - -} diff --git a/shared/lib/Chrono/Service/IServiceEntityMutable.php b/shared/lib/Chrono/Service/IServiceEntityMutable.php deleted file mode 100644 index ebe4575..0000000 --- a/shared/lib/Chrono/Service/IServiceEntityMutable.php +++ /dev/null @@ -1,81 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Service; - -use KTXF\Chrono\Entity\IEntityMutable; - -interface IServiceEntityMutable extends IServiceBase { - - public const CAPABILITY_ENTITY_CREATE = 'EntityCreate'; - public const CAPABILITY_ENTITY_MODIFY = 'EntityModify'; - public const CAPABILITY_ENTITY_DESTROY = 'EntityDestroy'; - public const CAPABILITY_ENTITY_COPY = 'EntityCopy'; - public const CAPABILITY_ENTITY_MOVE = 'EntityMove'; - - /** - * Creates a fresh entity of the specified type - * - * @since 2025.05.01 - * - * @return IEntityMutable - */ - public function entityFresh(): IEntityMutable; - - /** - * Creates a new entity in the specified collection - * - * @since 2025.05.01 - * - * @param string $collection The collection to create this entity in - * @param IEntityMutable $entity The entity to create - * @param array $options Additional options for the entity creation - * - * @return IEntityMutable - * - * @throws \KTXF\Resource\Exceptions\InvalidArgumentException - * @throws \KTXF\Resource\Exceptions\UnsupportedException - * @throws \KTXF\Resource\Exceptions\UnauthorizedException - */ - public function entityCreate(string|int $collection, IEntityMutable $entity, array $options): IEntityMutable; - - /** - * Modifies an existing entity in the specified collection - * - * @since 2025.05.01 - * - * @param string $collection The collection containing the entity to modify - * @param string $identifier The ID of the entity to modify - * @param IEntityMutable $entity The entity with modifications - * - * @return IEntityMutable - * - * @throws \KTXF\Resource\Exceptions\InvalidArgumentException - * @throws \KTXF\Resource\Exceptions\UnsupportedException - * @throws \KTXF\Resource\Exceptions\UnauthorizedException - */ - public function entityModify(string|int $collection, string|int $identifier, IEntityMutable $entity): IEntityMutable; - - /** - * Destroys an existing entity in the specified collection - * - * @since 2025.05.01 - * - * @param string $collection The collection containing the entity to destroy - * @param string $identifier The ID of the entity to destroy - * - * @return IEntityMutable - * - * @throws \KTXF\Resource\Exceptions\InvalidArgumentException - * @throws \KTXF\Resource\Exceptions\UnsupportedException - * @throws \KTXF\Resource\Exceptions\UnauthorizedException - */ - public function entityDestroy(string|int $collection, string|int $identifier): IEntityMutable; - -} diff --git a/shared/lib/Chrono/Service/IServiceMutable.php b/shared/lib/Chrono/Service/IServiceMutable.php deleted file mode 100644 index 02ece43..0000000 --- a/shared/lib/Chrono/Service/IServiceMutable.php +++ /dev/null @@ -1,30 +0,0 @@ - - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -namespace KTXF\Chrono\Service; - -use KTXF\Json\JsonDeserializable; - -interface IServiceMutable extends IServiceBase, JsonDeserializable { - - /** - * Sets the localized human friendly name of this service (e.g. ACME Company Calendar Service) - * - * @since 2025.05.01 - */ - public function setLabel(string $value): self; - - /** - * Sets the active status of this service - * - * @since 2025.05.01 - */ - public function setEnabled(bool $value): self; - -} diff --git a/shared/lib/Chrono/Service/ServiceBaseInterface.php b/shared/lib/Chrono/Service/ServiceBaseInterface.php new file mode 100644 index 0000000..9d1da51 --- /dev/null +++ b/shared/lib/Chrono/Service/ServiceBaseInterface.php @@ -0,0 +1,198 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Service; + +use KTXF\Chrono\Collection\CollectionBaseInterface; +use KTXF\Resource\Delta\Delta; +use KTXF\Resource\Filter\IFilter; +use KTXF\Resource\Provider\ResourceServiceBaseInterface; +use KTXF\Resource\Range\IRange; +use KTXF\Resource\Range\RangeType; +use KTXF\Resource\Sort\ISort; + +/** + * Chrono Service Base Interface + * + * @since 2025.05.01 + */ +interface ServiceBaseInterface extends ResourceServiceBaseInterface { + + // Collection capabilities + public const CAPABILITY_COLLECTION_LIST = 'CollectionList'; + public const CAPABILITY_COLLECTION_LIST_FILTER = 'CollectionListFilter'; + public const CAPABILITY_COLLECTION_LIST_SORT = 'CollectionListSort'; + public const CAPABILITY_COLLECTION_EXTANT = 'CollectionExtant'; + public const CAPABILITY_COLLECTION_FETCH = 'CollectionFetch'; + // Collection Filter + public const CAPABILITY_COLLECTION_FILTER_LABEL = 'label'; + public const CAPABILITY_COLLECTION_FILTER_CONTENTS = 'contents'; + // Collection Sort + public const CAPABILITY_COLLECTION_SORT_LABEL = 'label'; + public const CAPABILITY_COLLECTION_SORT_RANK = 'rank'; + // Entity capabilities + public const CAPABILITY_ENTITY_LIST = 'EntityList'; + public const CAPABILITY_ENTITY_LIST_FILTER = 'EntityListFilter'; + public const CAPABILITY_ENTITY_LIST_SORT = 'EntityListSort'; + public const CAPABILITY_ENTITY_LIST_RANGE = 'EntityListRange'; + public const CAPABILITY_ENTITY_DELTA = 'EntityDelta'; + public const CAPABILITY_ENTITY_EXTANT = 'EntityExtant'; + public const CAPABILITY_ENTITY_FETCH = 'EntityFetch'; + // Filter capabilities + public const CAPABILITY_ENTITY_FILTER_ALL = '*'; + public const CAPABILITY_ENTITY_FILTER_ID = 'id'; + public const CAPABILITY_ENTITY_FILTER_URID = 'urid'; + public const CAPABILITY_ENTITY_FILTER_LABEL = 'label'; + // Sort capabilities + public const CAPABILITY_ENTITY_SORT_ID = 'id'; + public const CAPABILITY_ENTITY_SORT_URID = 'urid'; + public const CAPABILITY_ENTITY_SORT_LABEL = 'label'; + public const CAPABILITY_ENTITY_SORT_PRIORITY = 'priority'; + // Range capabilities + public const CAPABILITY_ENTITY_RANGE_TALLY = 'tally'; + public const CAPABILITY_ENTITY_RANGE_TALLY_ABSOLUTE = 'absolute'; + public const CAPABILITY_ENTITY_RANGE_TALLY_RELATIVE = 'relative'; + public const CAPABILITY_ENTITY_RANGE_DATE = 'date'; + + public const JSON_TYPE = 'chrono.service'; + + /** + * Lists all collections in this service + * + * @since 2025.05.01 + * + * @param IFilter|null $filter Optional filter criteria + * @param ISort|null $sort Optional sort order + * + * @return array Collections indexed by ID + */ + public function collectionList(string|int $location, ?IFilter $filter = null, ?ISort $sort = null): array; + + /** + * Creates a filter builder for collections + * + * @since 2025.05.01 + * + * @return IFilter + */ + public function collectionListFilter(): IFilter; + + /** + * Creates a sort builder for collections + * + * @since 2025.05.01 + * + * @return ISort + */ + public function collectionListSort(): ISort; + + /** + * Checks if collections exist + * + * @since 2025.05.01 + * + * @param string|int ...$identifiers Collection IDs to check + * + * @return array Map of ID => exists + */ + public function collectionExtant(string|int $location, string|int ...$identifiers): array; + + /** + * Fetches a single collection + * + * @since 2025.05.01 + * + * @param string|int $identifier Collection ID + * + * @return CollectionBaseInterface|null Collection or null if not found + */ + public function collectionFetch(string|int $identifier): ?CollectionBaseInterface; + + /** + * Lists messages in a collection + * + * @since 2025.05.01 + * + * @param string|int $collection Collection ID + * @param IFilter|null $filter Optional filter criteria + * @param ISort|null $sort Optional sort order + * @param IRange|null $range Optional pagination + * @param array|null $properties Optional message properties to fetch + * + * @return array Messages indexed by ID + */ + public function entityList(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array; + + /** + * Creates a filter builder for messages + * + * @since 2025.05.01 + * + * @return IFilter + */ + public function entityListFilter(): IFilter; + + /** + * Creates a sort builder for messages + * + * @since 2025.05.01 + * + * @return ISort + */ + public function entityListSort(): ISort; + + /** + * Creates a range builder for messages + * + * @since 2025.05.01 + * + * @param RangeType $type Range type (offset, cursor, etc.) + * + * @return IRange + */ + public function entityListRange(RangeType $type): IRange; + + /** + * Gets incremental changes since last sync + * + * @since 2025.05.01 + * + * @param string|int $collection Collection ID + * @param string $signature Sync token from previous sync + * @param string $detail Detail level: 'ids', 'minimal', 'full' + * + * @return array ['signature' => string, 'added' => array, 'modified' => array, 'removed' => array] + */ + public function entityDelta(string|int $collection, string $signature, string $detail = 'ids'): Delta; + + /** + * Checks if messages exist + * + * @since 2025.05.01 + * + * @param string|int $collection Collection ID + * @param string|int ...$identifiers Message IDs to check + * + * @return array Map of ID => exists + */ + public function entityExtant(string|int $collection, string|int ...$identifiers): array; + + /** + * Fetches one or more entities + * + * @since 2025.05.01 + * + * @param string|int $collection Collection ID + * @param string|int ...$identifiers Message IDs to fetch + * + * @return array Messages indexed by ID + */ + public function entityFetch(string|int $collection, string|int ...$identifiers): array; + +} diff --git a/shared/lib/Chrono/Service/ServiceCollectionMutableInterface.php b/shared/lib/Chrono/Service/ServiceCollectionMutableInterface.php new file mode 100644 index 0000000..022e147 --- /dev/null +++ b/shared/lib/Chrono/Service/ServiceCollectionMutableInterface.php @@ -0,0 +1,73 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Service; + +use KTXF\Chrono\Collection\CollectionBaseInterface; +use KTXF\Chrono\Collection\CollectionMutableInterface; + +/** + * Chrono Service Collection Mutable Interface + * + * @since 2025.05.01 + */ +interface ServiceCollectionMutableInterface extends ServiceBaseInterface { + + public const CAPABILITY_COLLECTION_CREATE = 'CollectionCreate'; + public const CAPABILITY_COLLECTION_UPDATE = 'CollectionUpdate'; + public const CAPABILITY_COLLECTION_DELETE = 'CollectionDelete'; + + /** + * Creates a fresh collection instance for configuration + * + * @since 2025.05.01 + * + * @return CollectionMutableInterface Fresh collection object + */ + public function collectionFresh(): CollectionMutableInterface; + + /** + * Creates a new collection + * + * @since 2025.05.01 + * + * @param string|int|null $location Parent collection ID (null for root) + * @param CollectionMutableInterface $collection Collection to create + * @param array $options Protocol-specific options + * + * @return CollectionBaseInterface Created collection with assigned ID + */ + public function collectionCreate(string|int|null $location, CollectionMutableInterface $collection, array $options = []): CollectionBaseInterface; + + /** + * Updates an existing collection + * + * @since 2025.05.01 + * + * @param string|int $identifier Collection ID + * @param CollectionMutableInterface $collection Updated collection data + * + * @return CollectionBaseInterface Updated collection + */ + public function collectionUpdate(string|int $identifier, CollectionMutableInterface $collection): CollectionBaseInterface; + + /** + * Deletes a collection + * + * @since 2025.05.01 + * + * @param string|int $identifier Collection ID + * @param bool $force Force deletion even if not empty + * @param bool $recursive Recursively delete contents + * + * @return bool True if deleted + */ + public function collectionDelete(string|int $identifier, bool $force = false, bool $recursive = false): bool; + +} diff --git a/shared/lib/Chrono/Service/ServiceConfigurableInterface.php b/shared/lib/Chrono/Service/ServiceConfigurableInterface.php new file mode 100644 index 0000000..699f65e --- /dev/null +++ b/shared/lib/Chrono/Service/ServiceConfigurableInterface.php @@ -0,0 +1,26 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Service; + +use KTXF\Resource\Provider\ResourceServiceConfigureInterface; + +/** + * Chrono Service Configurable Interface + * + * Extends base service interface with setter methods for mutable properties. + * Used for service configuration and updates. + * + * @since 2025.05.01 + */ +interface ServiceConfigurableInterface extends ServiceMutableInterface, ResourceServiceConfigureInterface { + + public const JSON_TYPE = ServiceBaseInterface::JSON_TYPE; + +} diff --git a/shared/lib/Chrono/Service/ServiceEntityMutableInterface.php b/shared/lib/Chrono/Service/ServiceEntityMutableInterface.php new file mode 100644 index 0000000..95d9f30 --- /dev/null +++ b/shared/lib/Chrono/Service/ServiceEntityMutableInterface.php @@ -0,0 +1,77 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Service; + +use KTXF\Chrono\Entity\EntityBaseInterface; +use KTXF\Chrono\Entity\EntityMutableInterface; + +/** + * Chrono Service Entity Mutable Interface + * + * Optional interface for services that support entity CRUD operations. + * Provides entity creation, modification, deletion, copying, moving, and flag management. + * + * @since 2025.05.01 + */ +interface ServiceEntityMutableInterface extends ServiceBaseInterface { + + public const CAPABILITY_ENTITY_CREATE = 'EntityCreate'; + public const CAPABILITY_ENTITY_UPDATE = 'EntityUpdate'; + public const CAPABILITY_ENTITY_DELETE = 'EntityDelete'; + public const CAPABILITY_ENTITY_COPY = 'EntityCopy'; + public const CAPABILITY_ENTITY_MOVE = 'EntityMove'; + + /** + * Creates a fresh entity instance for composition + * + * @since 2025.05.01 + * + * @return EntityMutableInterface Fresh entity object + */ + public function entityFresh(): EntityMutableInterface; + + /** + * Creates/imports an entity into a collection + * + * @since 2025.05.01 + * + * @param string|int $collection collection identifier + * @param EntityMutableInterface $entity Entity data + * @param array $options additional options + * + * @return EntityBaseInterface Created entity + */ + public function entityCreate(string|int $collection, EntityMutableInterface $entity, array $options = []): EntityBaseInterface; + + /** + * Modifies an existing entity + * + * @since 2025.05.01 + * + * @param string|int $collection Collection identifier + * @param string|int $identifier Entity identifier + * @param EntityMutableInterface $entity Entity data + * + * @return EntityBaseInterface Modified entity + */ + public function entityUpdate(string|int $collection, string|int $identifier, EntityMutableInterface $entity): EntityBaseInterface; + /** + * Deletes an existing entity in the specified collection + * + * @since 2025.05.01 + * + * @param string|int $collection Collection identifier + * @param string|int $identifier Entity identifier to delete + * + * @return EntityBaseInterface Deleted entity + */ + public function entityDelete(string|int $collection, string|int $identifier): EntityBaseInterface; + +} diff --git a/shared/lib/Chrono/Service/ServiceMutableInterface.php b/shared/lib/Chrono/Service/ServiceMutableInterface.php new file mode 100644 index 0000000..bd76fc7 --- /dev/null +++ b/shared/lib/Chrono/Service/ServiceMutableInterface.php @@ -0,0 +1,22 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace KTXF\Chrono\Service; + +/** + * Chrono Service Mutable Interface + * + * Extends base service interface with setter methods for mutable properties. + * Used for service configuration and updates. + * + * @since 2025.05.01 + */ +interface ServiceMutableInterface extends ServiceBaseInterface { + +} diff --git a/shared/lib/Resource/Provider/ResourceServiceBaseInterface.php b/shared/lib/Resource/Provider/ResourceServiceBaseInterface.php index 539d98e..652507c 100644 --- a/shared/lib/Resource/Provider/ResourceServiceBaseInterface.php +++ b/shared/lib/Resource/Provider/ResourceServiceBaseInterface.php @@ -75,7 +75,7 @@ interface ResourceServiceBaseInterface extends JsonSerializable { * * @return ResourceServiceLocationInterface */ - public function getLocation(): ResourceServiceLocationInterface; + public function getLocation(): ResourceServiceLocationInterface | null; /** * Gets the identity information of this service @@ -84,7 +84,7 @@ interface ResourceServiceBaseInterface extends JsonSerializable { * * @return ResourceServiceIdentityInterface */ - public function getIdentity(): ResourceServiceIdentityInterface; + public function getIdentity(): ResourceServiceIdentityInterface | null; /** * Gets the auxiliary information of this service