Skip to content

Commit

Permalink
Impl. file domain layer
Browse files Browse the repository at this point in the history
[Re #1543]

* Also added a generic function in the gpml.domain.types namespace to
generate the Malli schema for a given type. Which comes in handy as we
always endup writing the same code for enums.
  • Loading branch information
lucassousaf committed Aug 9, 2023
1 parent 20bb02c commit f35385f
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
70 changes: 70 additions & 0 deletions backend/src/gpml/domain/file.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
(ns gpml.domain.file
(:require [clojure.string :as str]
[gpml.domain.miscellaneous :as dom.misc]
[gpml.domain.types :as dom.types]
[gpml.util :as util]
[malli.core :as m])
(:import [java.io File]))

(def ^:const object-key-pattern
"Pattern to define the object key of the file in the object storage.
Example:
- event/images/12fd5c76-7f12-4084-a9ca-a834d030977d"
"ENTITY-KEY/FILE-KEY/FILE-ID")

(def file-schema
(m/schema
[:map
{:closed true}
[:id uuid?]
[:object-key
[:string
{:min 1}]]
[:name
[:string
{:min 1}]]
[:alt-desc
{:optional true}
[:maybe
[:string
{:min 1}]]]
[:type
[:string
{:min 1}]]
[:extension
{:optional true}
[:maybe
[:string]]]
[:visibility
(dom.types/get-type-schema :file-visibility)]
[:content
{:optional true}
[:or
dom.misc/base64-schema
[:fn #(instance? File %)]]]
[:created-at inst?]
[:last-updated-at
{:optional true}
inst?]]))

(defn create-file-object-key
[entity-key file-key file-id]
(-> object-key-pattern
(str/replace #"ENTITY-KEY" (name entity-key))
(str/replace #"FILE-KEY" (name file-key))
(str/replace #"FILE-ID" (str file-id))))

(defn base64->file
[payload entity-key file-key visibility]
(let [[_ ^String content-type ^String content] (re-find #"^data:(\S+);base64,(.*)$" payload)
[_ extension] (str/split content-type #"\/")
file-id (util/uuid)]
{:id file-id
:object-key (create-file-object-key entity-key file-key file-id)
:name (format "%s-%s" (name entity-key) (util/uuid))
:alt-desc nil
:type content-type
:extension extension
:visibility visibility
:content content}))
12 changes: 12 additions & 0 deletions backend/src/gpml/domain/miscellaneous.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(ns gpml.domain.miscellaneous
(:require [malli.core :as m]))

(def base64-schema
(m/schema
[:and
[:string]
[:or
[:= ""]
[:and
[:re #"[0-9a-zA-Z+/]+={0,2}"]
[:fn #(= 0 (rem (count %) 4))]]]]))
26 changes: 25 additions & 1 deletion backend/src/gpml/domain/types.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns gpml.domain.types
"Well-known domain global types definitions. These types are used
across the domain model by several entities.")
across the domain model by several entities."
(:require [malli.core :as m]))

;; TODO: Refactor enums to be keywords instead of strings.
(def ^:const review-statuses
Expand Down Expand Up @@ -77,3 +78,26 @@
"financing_resource"
"technical_resource"
"action_plan"})

(def ^:const file-visibility
"Informs about a file's accessability privilegies."
#{:private
:public})

(def ^:const enum-types
{:review-status review-statuses
:reviewer-status reviewer-review-statuses
:geo-coverage-type geo-coverage-types
:association-type association-types
:resource-source resource-source-types
:topic-entity-table topic-entity-tables
:topic-type topic-types
:resource-type resources-types
:file-visibility file-visibility})

(defn get-type-schema
[type-name]
(m/schema
[:and
[:keyword]
(apply conj [:enum] (get enum-types type-name))]))

0 comments on commit f35385f

Please sign in to comment.