From 529efb3668cf364a8787fa320ab822c1ce9f3210 Mon Sep 17 00:00:00 2001 From: Olli Date: Thu, 28 Aug 2025 14:36:47 +0200 Subject: [PATCH] Add schema description and JSON schema files --- README.md | 76 ++++++++++++++++++++++++++++++++++++++++++++ schema/activity.json | 22 +++++++++++++ schema/project.json | 22 +++++++++++++ schema/time.json | 36 +++++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 README.md create mode 100644 schema/activity.json create mode 100644 schema/project.json create mode 100644 schema/time.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..52e21c5 --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +# Time Files + +Time Files is both a specification and a reference implementation for tracking +project time. + +## Schema + +All data is stored in JSON files using `.json` as file extension. Each entity +uses its own folder with each instance in a dedicated file. For some entities +sub-folders are used. + +Files and folders are structured as follows: + + projects + .json + .json + activities + / + .json + .json + / + .json + .json + times/ + / + / + / + .json + .json + .json + timer.json + +Project files are stored in a “projects” folder using the UUID as file name and +the following content: + +```json +{ + "id": "UUID of the project", + "title": "Human-readable title" +} +``` + +Activity files are stored in an “activities” folder with the UUID of the project +they belong to as sub-folder. They have the following content: + +```json +{ + "id": "UUID of the activity", + "title": "Human-readable title" +} +``` + +Time files are stored in a “times” folder with sub-folders for the year, the +month and the day. If a time entry spans across multiple days, it has to be +split. They have the following content: + +```json +{ + "id": "UUID of the time entry", + "project": "UUID of the project (optional)", + "activity": "UUID of the activity (optional)", + "start": "Start time in ISO format", + "end": "End time in ISO format (optional)" +} +``` + +Additionally, the file “timer.json” is stored in the “times” folder containing +the currently active time tracking. End `end` property is empty in that case. +Both `project` and `activity` can be empty as well to allow both to be set after +starting time tracking. + +The file schemata are available as JSON schema: + +* [project](./schema/project.json) +* [activity](./schema/activity.json) +* [time](./schema/time.json) diff --git a/schema/activity.json b/schema/activity.json new file mode 100644 index 0000000..10dadbb --- /dev/null +++ b/schema/activity.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://www.suruatoel.xyz/codes/protime/activity.json", + "title": "Activity", + "description": "An activity entry", + "type": "object", + "properties": { + "id": { + "description": "", + "type": "string", + "format": "uuid" + }, + "title": { + "description": "", + "type": "string" + } + }, + "required": [ + "id", + "title" + ] +} diff --git a/schema/project.json b/schema/project.json new file mode 100644 index 0000000..2f2c4ca --- /dev/null +++ b/schema/project.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://www.suruatoel.xyz/codes/protime/project.json", + "title": "Project", + "description": "A project entry", + "type": "object", + "properties": { + "id": { + "description": "", + "type": "string", + "format": "uuid" + }, + "title": { + "description": "", + "type": "string" + } + }, + "required": [ + "id", + "title" + ] +} diff --git a/schema/time.json b/schema/time.json new file mode 100644 index 0000000..ddcc07b --- /dev/null +++ b/schema/time.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://www.suruatoel.xyz/codes/protime/time.json", + "title": "Time", + "description": "A time entry", + "type": "object", + "properties": { + "id": { + "description": "", + "type": "string", + "format": "uuid" + }, + "project": { + "description": "", + "type": "string" + }, + "activity": { + "description": "", + "type": "string" + }, + "start": { + "description": "", + "type": "string", + "format": "date-time" + }, + "end": { + "description": "", + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "start" + ] +}