├── .envrc ├── .github ├── assets │ └── banner.webp └── workflows │ ├── main.yaml │ └── pr_check.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── backend ├── .gitignore ├── .sqlx │ ├── query-0425aa387b7928417c59e1d127448fdce052e0c081452e9fbbed8a2d252349f9.json │ ├── query-09ce979ec7e78f1e557ca00a3bf68797b369281a26682919cfbc8c447725202d.json │ ├── query-121c55cfc66bfdcadda3b6c879ec656848b554b808b614a60d3655567d7f7d48.json │ ├── query-17a7cade3e2aa93f9d6f1beddbcb164f6ab2dda148f167497edf4972e753d585.json │ ├── query-1c8aa530619f6ef63665671e7999fa2ee0a06d4d2ff0efa530600be4e1369519.json │ ├── query-1da41567d2f9913ad2e43cd889bf26a2859a2944030ca6a52917f7d3c7cf3947.json │ ├── query-214ac6fc5d8548cfd0d8fd97411ec6d943f7d6b84487f78b059535cf10f4a9a7.json │ ├── query-299e21ab01afeaa2bad80845ad860dbf9b8d963da90589a445a3b5071418a942.json │ ├── query-30141d915969c5d856ef98a52cfb29775d747273702512ff0e94c9f53b9cb6ae.json │ ├── query-3357c72b39b5cfb154ed22ed2471e12555141ffcfaefa7c068b2f4c8f73c9c64.json │ ├── query-3566e1d5ed46ca2481e39c212945686666e172577e0b4276be88e694e9947c96.json │ ├── query-3775dfc21e07361d7e0d4915fdb35c03403e04a2f1149f05ced03dbde368b1ed.json │ ├── query-3860a60a914266bf4386fe9262af2896e70f65a23683155ac0551f253ad176b9.json │ ├── query-3988d3372138cdb9d2be01bf08ec3a24517a2df8cce30b22f6ebfa45173b6cf3.json │ ├── query-39b658e5d1fd32d876be8723c09a2c3b4f4006242e24fab776191f27fcab862b.json │ ├── query-3c85c684a162418d90961456e5231bca0002f4e80da2bfcf62c4318c20be8f7f.json │ ├── query-3ec8dc8e90248fb05b43c65ed1944afe19b1248c62a022da4df181a93a11bd0b.json │ ├── query-435644c7645eb37d5c869105ddbc4172230801ba506d4aae70c84f8ea8da8d22.json │ ├── query-45761ad61a0aa459603cf56ea6e69f24cb7c02c3fece6708f6e4a220d636e9c9.json │ ├── query-47dcef54f2d7b53f35623f5747b4a2dd89b45756b33e94879c2860ea5cb5f8df.json │ ├── query-4de1c6da26f19d7f56049709bc786db9a4bc74d864a3f1184ea2ab0a4988e869.json │ ├── query-50293c2e54af11d4c2a553e29b671cef087a159c6ee7182d8ca929ecb748f3b7.json │ ├── query-50ca7413465d5fc7facfcb8598fb02e6cf93bf1d75dd33eae15052bf7ba5829b.json │ ├── query-51ea0fa88841a753ffa0b63f1771649ef335c8de49b73146e3a2831e71419b70.json │ ├── query-5316deb346a27cddcdce842ef5da51857ea95762639d548ce36918dc2027d1d2.json │ ├── query-5c948122c3a1469040cf14571318ec26a5ff98d08011d3db5d6e41377a810b41.json │ ├── query-5e6df0456cb4b90598b6f8d04bc86069d5c3558bd41481674ed50d6926d6d93e.json │ ├── query-5f5380734b3f0fa065b1830ccbacdf2ef38d24f4188b17858e79e0ff38464b69.json │ ├── query-63ca3d01283df9eae426e9ccdc3d092272f7ea3b327f5b91db9bd07343d9a651.json │ ├── query-6e6b275479ea4753c86bd3c06c4b12c65e764824fc5a82d3ebd60d17bc667233.json │ ├── query-73773148b323ae294e78a121105d0f02f74cb91cc91ad87e33880e15996e7419.json │ ├── query-774a79f460f88cbacfe0a7cd963ab3a073f83afc9eb0198fe440405e54687dc8.json │ ├── query-7b168898203679d14f1ccbcd1715ab2069b112d2df80ac40f80b3a63ee8ca92e.json │ ├── query-7f9dad2abb0f3abd4339420e1709ed1553f8dfe420760910de8a2ab6bec3073f.json │ ├── query-80d4efd69f7d05138746b053eaacf15818addf149b6c017ac8b56193d6a10245.json │ ├── query-857475123f7d8c8793f2021635520ecaa0c912138ac77009f2461a228c106c7b.json │ ├── query-8690986b3442cedfce1de17432b38892be2fdfe2daee611e8b64970772acb17b.json │ ├── query-93ea354a30d421bc27be9f28bfc99efd68d52f47025750e6663ea76ea529a3b7.json │ ├── query-9617c158d7c8cb409d9db78cfc77c783b9553ae0745c5f464dfb73557bca0f19.json │ ├── query-97070b0146d22a4b78469d02f6b842034eb8d76d219272349e7616fde7fac8ed.json │ ├── query-980dc595abe611c59bd1cc6d46dfb52a46b7fe1d830f37fdfd817121d7f1a56a.json │ ├── query-a04146ed7909d632cdd53d1df7f3f84b546863d102dd9edcc34f8655aabffb36.json │ ├── query-a2215f2b60f0171eff8a5c1f5e3c70f1ef1912a68005f77837fc0a3336e30304.json │ ├── query-a26eb8704bb81f1b60bb285994f6c79ba5f7c06c3f8fd00722f7e571727573f7.json │ ├── query-a4ad29d1517628e943a7ae118deda6fdb8dbecf42873fd2ce76c825e60fcb7ec.json │ ├── query-a4d1f12942fa45b55e31dc8f35499723e0385de509d1f81eb37cb30a2e2d73e4.json │ ├── query-a9447d27feca9fbef65a6233465c3fab45e39a4193d222338506c348e9abff56.json │ ├── query-ae38d2ce78819912784f250c1d2418bcea27807509963d6a1d3dc69a8d67df41.json │ ├── query-b0fdb9fa87e8ac1dc17e10a273355e4f20d9f920aa9fd0f7d5a216e5d4df9f2a.json │ ├── query-b3f2cc59f7f9579cb89baf7bcd5b25c8a7edf07d0b8f1782117a97fcb097d6df.json │ ├── query-b6ca4088314dfb1de406a59fd977b67123b085062e19f586a116868677338682.json │ ├── query-b96e044361f8664aef6dcf8ca00cf5d657286d7dba845a0551efc6677d40378d.json │ ├── query-c23fb52d04418585be96aca83b155e5c882d692f86a72281b2a0b2c7d9c5cefa.json │ ├── query-cb733f3d3b968f2b2e3672b6b24db324e26f5082cdcee69c35c677660a94f532.json │ ├── query-d0645eb40bf50d186b229cca83e2e4df322b902a68a86a4e82ee1fc47e031db6.json │ ├── query-d167f47a4e4b04f0616d205cd7c3e59619e9fa861a22334f27d852073f09adbf.json │ ├── query-d4667242ba0c1d645f19ad1c560d2a6cca50b06f187095053888bee95c1fd9c1.json │ ├── query-d7a7af9e4da80ce587bb5e92896616e5907f0e256342b9ffb8600c4fa27cc18d.json │ ├── query-d7fa934a55e704afce7ad68af9502dc01b5ba5a467708225c63870f6b5eeeece.json │ ├── query-d81da0cb8b8ee7f72bb84ecc104c96e274ecad13eda24e84a7aa7c856b8ca9e6.json │ ├── query-d8d142f7c2bb25eb449c391e3ca4f791f43d9188cac57b88d7839503a8e7b252.json │ ├── query-dce78dca1b1ad3816445a421c9c2888d2c68c54545d35ba851681cb32842947b.json │ ├── query-df114f7704654e85ae8a9433a91d1c4d3f603ec4992a6845c87b282bc870320e.json │ ├── query-e1c14ad1400bb468668b8e3f8d3aeccc214f090685724e76b1ec6c92be7166bd.json │ ├── query-e4bcd40211792477d6dff5d1d64d5b5b6ae3904d613c8285f750a8c6b5bd8e25.json │ ├── query-e625c5d9489f670a20dd88f3383937a290bb75a1cd229cc03e840d84a6b37ba2.json │ ├── query-e767b125954189cb00b4f7661e1f758534cf0aec5b5bc0d4c550394d449c3a4d.json │ ├── query-e92063f48832afff02878e598c3b59729ba8ff51fd774558cd26bf34e2957f1a.json │ ├── query-f611befc43dedf445e68c79972b1c4c7a02b3b0605bcf480fc99f6721891eb66.json │ ├── query-fbf5909594b8e0fc66c88fb8bf9f58fbd75eff94d127062e6d60684f8f82b8f7.json │ ├── query-fd9c4f718c8d31bf339faf83d4c5922b4f0a4a79dd6da1bc2728a93811b27e6e.json │ └── query-ffed961cdeb582dadde70c53b98dcc677c2a045ebac44669ef8a02e7a67a3a30.json ├── Cargo.lock ├── Cargo.toml ├── build.rs ├── migrations │ ├── 20240322224019_init_base_models.sql │ ├── 20240322224230_create_entities_cache.sql │ ├── 20240322224255_requests_for_entities_cache.sql │ └── 20240608185144_util_functions.sql └── src │ ├── api.rs │ ├── api │ ├── admin.rs │ ├── admin │ │ ├── access_tokens.rs │ │ ├── auth.rs │ │ ├── categories.rs │ │ ├── comments.rs │ │ ├── entities.rs │ │ ├── families.rs │ │ ├── options.rs │ │ ├── statistics.rs │ │ ├── tags.rs │ │ └── users.rs │ ├── auth.rs │ ├── icons.rs │ ├── map.rs │ └── root.rs │ ├── config.rs │ ├── doc.rs │ ├── helpers │ ├── deserializers.rs │ ├── hcaptcha.rs │ ├── mod.rs │ └── postgis_polygons.rs │ ├── main.rs │ └── models │ ├── access_token.rs │ ├── category.rs │ ├── comment.rs │ ├── entity.rs │ ├── entity_cache.rs │ ├── family.rs │ ├── icon.rs │ ├── mod.rs │ ├── options.rs │ ├── statistics.rs │ ├── tag.rs │ └── user.rs ├── container_release ├── flake.lock ├── flake.nix ├── frontend ├── .gitignore ├── app.vue ├── assets │ ├── logo_colored.svg │ ├── logo_main.svg │ ├── logo_secondary.svg │ ├── logo_square.svg │ ├── logo_square_white.svg │ ├── main.css │ └── richtext.css ├── components │ ├── AppIcon.vue │ ├── CategoryTag.vue │ ├── CommentsDisplayer.vue │ ├── DisplayedTag.vue │ ├── NominatimPicker.vue │ ├── PolygonDrawer.vue │ ├── RequiredIndicator.vue │ ├── SingleEntityMap.vue │ ├── StartPopup.vue │ ├── admin │ │ ├── EditDeleteButtons.vue │ │ ├── EntityKinshipTable.vue │ │ ├── Navbar.vue │ │ ├── Sidebar.vue │ │ ├── UserAvatar.vue │ │ ├── families │ │ │ ├── EditForm.vue │ │ │ └── EditFormJson.vue │ │ └── input │ │ │ ├── ColorField.vue │ │ │ ├── EntitySelect.vue │ │ │ ├── IconUpload.vue │ │ │ ├── NumberField.vue │ │ │ ├── PolicyPermissionField.vue │ │ │ ├── SwitchField.vue │ │ │ └── TextField.vue │ ├── form │ │ ├── Adresses.vue │ │ ├── CategorySelect.vue │ │ ├── DynamicField.vue │ │ └── TagSelect.vue │ └── viewer │ │ ├── CommentAddForm.vue │ │ ├── EntityAddForm.vue │ │ ├── FamilySwitcher.vue │ │ ├── FilterConfig.vue │ │ ├── FullResult.vue │ │ ├── Information.vue │ │ ├── Map.vue │ │ ├── Navbar.vue │ │ ├── RichTextEditor.vue │ │ ├── common │ │ ├── EntityDisplayer.vue │ │ ├── FormFields.vue │ │ └── ScoreJauge.vue │ │ └── map │ │ ├── Cluster.vue │ │ └── Marker.vue ├── composables │ └── useDarkMode.ts ├── error.vue ├── eslint.config.mjs ├── layouts │ └── admin-ui.vue ├── lib.d.ts ├── lib │ ├── admin-auth-middleware.ts │ ├── admin-client.ts │ ├── admin-state.ts │ ├── dompurify.ts │ ├── nominatim.ts │ ├── validation.ts │ ├── viewer-auth-middleware.ts │ ├── viewer-client.ts │ └── viewer-state.ts ├── nuxt.config.ts ├── openapi.json ├── package-lock.json ├── package.json ├── pages │ ├── add │ │ └── [token].vue │ ├── admin │ │ ├── [familyId] │ │ │ ├── categories │ │ │ │ ├── [id].vue │ │ │ │ ├── index.vue │ │ │ │ └── new-icon-[id].vue │ │ │ ├── comments │ │ │ │ ├── [id].vue │ │ │ │ └── pending.vue │ │ │ └── entities │ │ │ │ ├── [id].vue │ │ │ │ ├── index.vue │ │ │ │ ├── new.vue │ │ │ │ └── pending.vue │ │ ├── access-tokens │ │ │ ├── [id].vue │ │ │ ├── details │ │ │ │ └── [id].vue │ │ │ └── index.vue │ │ ├── config.vue │ │ ├── families │ │ │ ├── [id] │ │ │ │ ├── comments.vue │ │ │ │ ├── entities.vue │ │ │ │ └── general.vue │ │ │ ├── index.vue │ │ │ ├── new-icon-[id].vue │ │ │ └── new.vue │ │ ├── home.vue │ │ ├── index.vue │ │ ├── login.vue │ │ ├── tags │ │ │ ├── [id].vue │ │ │ └── index.vue │ │ └── users │ │ │ ├── [id].vue │ │ │ ├── index.vue │ │ │ └── self.vue │ ├── index.vue │ ├── map │ │ └── [token].vue │ └── search │ │ └── [token].vue ├── plugins │ ├── vue-hcaptcha.client.ts │ └── vue3-openlayers.client.ts ├── public │ └── default_favicon.ico ├── tailwind.config.js ├── theme.mjs └── tsconfig.json └── safehaven.code-workspace /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /.github/assets/banner.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SafeHavenMaps/safehaven/ebab389d5bea0aad487169660efd6ae577c82ea4/.github/assets/banner.webp -------------------------------------------------------------------------------- /.github/workflows/pr_check.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | branches: 4 | - main 5 | 6 | jobs: 7 | build: 8 | name: Build 9 | runs-on: ubuntu-latest 10 | 11 | services: 12 | postgres: 13 | image: postgis/postgis:16-3.4-alpine 14 | env: 15 | POSTGRES_PASSWORD: postgres 16 | ports: 17 | - 5432:5432 18 | 19 | steps: 20 | - name: Checkout code 21 | uses: actions/checkout@v4 22 | 23 | - name: Install Nix 24 | uses: cachix/install-nix-action@v27 25 | 26 | - name: Run project checks 27 | run: nix develop -c check_project 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .direnv 3 | .pgdata 4 | .idea 5 | result 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

SafeHaven Banner

2 | 3 | An open-source project to create a map of safe spaces for people in need. 4 | 5 | # WE ARE MIGRATING TO CODEBERG https://codeberg.org/SafeHaven/safehaven 6 | 7 | ## Deploy 8 | 9 | We provide docker images that are ready to deploy SafeHaven. You can find the releases in the 10 | [packages view of the SafeHavenMaps organisation](https://github.com/SafeHavenMaps/safehaven/pkgs/container/safehaven). 11 | 12 | ### Pre-requisites 13 | 14 | - A PostgreSQL server with PostGIS 15 | 16 | ### Prepare the database 17 | 18 | Create a database: 19 | 20 | ```sql 21 | CREATE DATABASE safehaven; 22 | ``` 23 | 24 | SafeHaven leverages PostgreSQL's full text search capabilities. You can help the indexer by setting a locale on the database: 25 | 26 | ```sql 27 | ALTER DATABASE safehaven SET default_text_search_config = 'pg_catalog.french'; 28 | ``` 29 | 30 | ## Configure 31 | 32 | SafeHaven is initialized with a default user named `admin` with a random password, which can be retrieved from backend logs. 33 | The administration panel will provide you with the ability to create new users and manage the application. 34 | 35 | To learn more about the configuration, you can visit [our documentation website](https://docs.safehavenmaps.org). 36 | 37 | ### Start the docker container: 38 | 39 | ```bash 40 | docker run -d \ 41 | -e SH__DATABASE__URL="postgresql://user:password@host/safehaven" \ # Set the database path 42 | -e SH__DATABASE__POOL_SIZE="5" \ # Set the number of connections to the database 43 | -e SH__SECURE_COOKIE="true" \ # Activate if you have a reverse proxy with HTTPS. 44 | -e SH__TOKEN_SECRET="SecretForValidatingAngSigningTokens" \ # Set a secret that will be used to sign sessions 45 | ghcr.io/safehavenmaps/safehaven:1.0.0 # Change latest to the latest version, check the releases 46 | ``` 47 | 48 | ## Contributing 49 | 50 | We welcome contributions from everyone. 51 | 52 | To spin up a development environment, follow these steps: 53 | 54 | **Pre-requisites:** 55 | 56 | - A working installation of Nix 57 | - Supports of Nix Flakes is required. 58 | - A PostgreSQL server with PostGIS in version 16 or higher. You can start one with `start_docker_postgresql`. 59 | 60 | **Steps:** 61 | 62 | - Clone the repository 63 | - Run `nix develop` to enter a development environment 64 | - Adjust the flake.nix variable to match your database database 65 | - Inside the `backend` folder 66 | - Run `sqlx migrate run` to create the database schema 67 | - Inside the `frontend` folder 68 | - Run `npm install` to install the dependencies 69 | - Inside the root folder: 70 | - Run `regen_api` to regenerate the API 71 | - _Optional:_ Run `start_docker_postgresql` to start a PostgreSQL server with PostGIS 72 | - Run `start_dev_env` to start the stack using process-compose 73 | 74 | ## License 75 | 76 | Licensed under the GNU General Public License v3.0, see [LICENSE](LICENSE). 77 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | Thank you for improving the security of our project. We take all security vulnerabilities seriously. 6 | 7 | If you discover a security vulnerability, please follow these steps: 8 | 9 | 1. Go to the [Security Advisories](https://github.com/SafeHavenMaps/safehaven/security/advisories) section of our GitHub repository. 10 | 2. Click on the "Report a vulnerability" button. 11 | 3. Follow the instructions to provide details about the vulnerability. 12 | 13 | This feature ensures that your report is kept confidential and allows us to work on a fix before the vulnerability is disclosed publicly. 14 | 15 | We appreciate your effort to make our project more secure. 16 | 17 | ## Supported Versions 18 | 19 | We provide security updates only for the latest release. There is no backporting of security fixes to older versions. 20 | 21 | | Version | Supported | 22 | | ------------- | ------------------ | 23 | | Latest Release| :white_check_mark: | 24 | | Older Versions| :x: | 25 | 26 | ## Security Updates 27 | 28 | We release security patches as soon as vulnerabilities are identified and fixed. Stay tuned to our [releases page](https://github.com/SafeHavenMaps/safehaven/releases) for updates. 29 | -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /backend/.sqlx/query-0425aa387b7928417c59e1d127448fdce052e0c081452e9fbbed8a2d252349f9.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT\n (SELECT COUNT(*) FROM entities WHERE moderated) AS \"total_entities!\",\n (SELECT COUNT(*) FROM comments WHERE moderated) AS \"total_comments!\",\n (SELECT COUNT(*) FROM entities WHERE NOT moderated) AS \"pending_entities!\",\n (SELECT COUNT(*) FROM comments WHERE NOT moderated) AS \"pending_comments!\",\n (SELECT COUNT(*) FROM access_tokens_visits WHERE visited_at >= NOW()::date - INTERVAL '30 days') AS \"total_visits_30_days!\",\n (SELECT COUNT(*) FROM access_tokens_visits WHERE visited_at >= NOW()::date - INTERVAL '7 days') AS \"total_visits_7_days!\",\n (\n WITH date_series AS (\n SELECT generate_series(\n NOW()::date - INTERVAL '30 days',\n NOW()::date,\n INTERVAL '1 day'\n )::date AS visit_date\n ),\n aggregated_visits AS (\n SELECT\n ds.visit_date,\n COALESCE(COUNT(atv.visited_at), 0) AS visit_count\n FROM\n date_series ds\n LEFT JOIN\n access_tokens_visits atv\n ON\n ds.visit_date = DATE(atv.visited_at)\n WHERE\n ds.visit_date >= NOW()::date - INTERVAL '30 days'\n GROUP BY\n ds.visit_date\n ORDER BY\n ds.visit_date\n )\n SELECT json_object_agg(\n TO_CHAR(visit_date, 'YYYY-MM-DD'),\n visit_count\n ) AS visits\n FROM aggregated_visits\n )\n AS \"visits_30_days!\"\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "total_entities!", 9 | "type_info": "Int8" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "total_comments!", 14 | "type_info": "Int8" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "pending_entities!", 19 | "type_info": "Int8" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "pending_comments!", 24 | "type_info": "Int8" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "total_visits_30_days!", 29 | "type_info": "Int8" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "total_visits_7_days!", 34 | "type_info": "Int8" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "visits_30_days!", 39 | "type_info": "Json" 40 | } 41 | ], 42 | "parameters": { 43 | "Left": [] 44 | }, 45 | "nullable": [ 46 | null, 47 | null, 48 | null, 49 | null, 50 | null, 51 | null, 52 | null 53 | ] 54 | }, 55 | "hash": "0425aa387b7928417c59e1d127448fdce052e0c081452e9fbbed8a2d252349f9" 56 | } 57 | -------------------------------------------------------------------------------- /backend/.sqlx/query-09ce979ec7e78f1e557ca00a3bf68797b369281a26682919cfbc8c447725202d.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT replace_tags_for_entity($1, $2)\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "replace_tags_for_entity", 9 | "type_info": "Void" 10 | } 11 | ], 12 | "parameters": { 13 | "Left": [ 14 | "Uuid", 15 | "UuidArray" 16 | ] 17 | }, 18 | "nullable": [ 19 | null 20 | ] 21 | }, 22 | "hash": "09ce979ec7e78f1e557ca00a3bf68797b369281a26682919cfbc8c447725202d" 23 | } 24 | -------------------------------------------------------------------------------- /backend/.sqlx/query-121c55cfc66bfdcadda3b6c879ec656848b554b808b614a60d3655567d7f7d48.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT id, title, (SELECT hash FROM icons WHERE id = icon_id) AS icon_hash,\n entity_form AS \"entity_form: Json
\", \n comment_form AS \"comment_form: Json\",\n sort_order,\n version\n FROM families\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "icon_hash", 19 | "type_info": "Bpchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "entity_form: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "comment_form: Json", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "sort_order", 34 | "type_info": "Int4" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | } 41 | ], 42 | "parameters": { 43 | "Left": [] 44 | }, 45 | "nullable": [ 46 | false, 47 | false, 48 | null, 49 | false, 50 | false, 51 | false, 52 | false 53 | ] 54 | }, 55 | "hash": "121c55cfc66bfdcadda3b6c879ec656848b554b808b614a60d3655567d7f7d48" 56 | } 57 | -------------------------------------------------------------------------------- /backend/.sqlx/query-17a7cade3e2aa93f9d6f1beddbcb164f6ab2dda148f167497edf4972e753d585.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT \n id AS \"id!\",\n entity_id AS \"entity_id!\",\n category_id AS \"category_id!\",\n tags_ids AS \"tags_ids!\",\n family_id AS \"family_id!\",\n display_name AS \"display_name!\",\n total_results AS \"total_results!\",\n total_pages AS \"total_pages!\",\n response_current_page AS \"response_current_page!\",\n hidden AS \"hidden!\"\n FROM search_entities_admin(\n $1,\n $2,\n $3,\n $4,\n $5,\n $6,\n $7,\n $8\n )\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id!", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "entity_id!", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "category_id!", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "tags_ids!", 24 | "type_info": "UuidArray" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "family_id!", 29 | "type_info": "Uuid" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "display_name!", 34 | "type_info": "Text" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "total_results!", 39 | "type_info": "Int8" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "total_pages!", 44 | "type_info": "Int8" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "response_current_page!", 49 | "type_info": "Int8" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "hidden!", 54 | "type_info": "Bool" 55 | } 56 | ], 57 | "parameters": { 58 | "Left": [ 59 | "Text", 60 | "Uuid", 61 | "Int8", 62 | "Int8", 63 | "UuidArray", 64 | "UuidArray", 65 | "UuidArray", 66 | "Jsonb" 67 | ] 68 | }, 69 | "nullable": [ 70 | null, 71 | null, 72 | null, 73 | null, 74 | null, 75 | null, 76 | null, 77 | null, 78 | null, 79 | null 80 | ] 81 | }, 82 | "hash": "17a7cade3e2aa93f9d6f1beddbcb164f6ab2dda148f167497edf4972e753d585" 83 | } 84 | -------------------------------------------------------------------------------- /backend/.sqlx/query-1c8aa530619f6ef63665671e7999fa2ee0a06d4d2ff0efa530600be4e1369519.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT\n id,\n title,\n family_id,\n default_status,\n (SELECT hash FROM icons WHERE id = icon_id) AS icon_hash,\n fill_color,\n border_color,\n version\n FROM categories\n WHERE NOT (id = ANY($1)) AND family_id = ANY($2)\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "family_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "default_status", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "icon_hash", 29 | "type_info": "Bpchar" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "fill_color", 34 | "type_info": "Varchar" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "border_color", 39 | "type_info": "Varchar" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "version", 44 | "type_info": "Int4" 45 | } 46 | ], 47 | "parameters": { 48 | "Left": [ 49 | "UuidArray", 50 | "UuidArray" 51 | ] 52 | }, 53 | "nullable": [ 54 | false, 55 | false, 56 | false, 57 | false, 58 | null, 59 | false, 60 | false, 61 | false 62 | ] 63 | }, 64 | "hash": "1c8aa530619f6ef63665671e7999fa2ee0a06d4d2ff0efa530600be4e1369519" 65 | } 66 | -------------------------------------------------------------------------------- /backend/.sqlx/query-1da41567d2f9913ad2e43cd889bf26a2859a2944030ca6a52917f7d3c7cf3947.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT e.id, e.display_name, e.category_id, e.created_at, e.hidden,\n e.moderated, e.updated_at,\n COALESCE(\n (SELECT array_agg(t.tag_id) FROM entity_tags t WHERE t.entity_id = e.id), \n array[]::uuid[]\n ) AS \"tags!\"\n FROM entities e\n WHERE NOT e.moderated\n ORDER BY created_at\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "display_name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "category_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "created_at", 24 | "type_info": "Timestamp" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "hidden", 29 | "type_info": "Bool" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "moderated", 34 | "type_info": "Bool" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "updated_at", 39 | "type_info": "Timestamp" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "tags!", 44 | "type_info": "UuidArray" 45 | } 46 | ], 47 | "parameters": { 48 | "Left": [] 49 | }, 50 | "nullable": [ 51 | false, 52 | false, 53 | false, 54 | false, 55 | false, 56 | false, 57 | false, 58 | null 59 | ] 60 | }, 61 | "hash": "1da41567d2f9913ad2e43cd889bf26a2859a2944030ca6a52917f7d3c7cf3947" 62 | } 63 | -------------------------------------------------------------------------------- /backend/.sqlx/query-214ac6fc5d8548cfd0d8fd97411ec6d943f7d6b84487f78b059535cf10f4a9a7.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n UPDATE users \n SET name = $2, password = $3, is_admin = $4 \n WHERE id = $1\n RETURNING\n id,\n name,\n is_admin,\n last_login\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "is_admin", 19 | "type_info": "Bool" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "last_login", 24 | "type_info": "Timestamp" 25 | } 26 | ], 27 | "parameters": { 28 | "Left": [ 29 | "Uuid", 30 | "Text", 31 | "Text", 32 | "Bool" 33 | ] 34 | }, 35 | "nullable": [ 36 | false, 37 | false, 38 | false, 39 | true 40 | ] 41 | }, 42 | "hash": "214ac6fc5d8548cfd0d8fd97411ec6d943f7d6b84487f78b059535cf10f4a9a7" 43 | } 44 | -------------------------------------------------------------------------------- /backend/.sqlx/query-299e21ab01afeaa2bad80845ad860dbf9b8d963da90589a445a3b5071418a942.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n DELETE FROM entities_entities\n WHERE parent_id = $1 AND child_id = $2\n ", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid", 9 | "Uuid" 10 | ] 11 | }, 12 | "nullable": [] 13 | }, 14 | "hash": "299e21ab01afeaa2bad80845ad860dbf9b8d963da90589a445a3b5071418a942" 15 | } 16 | -------------------------------------------------------------------------------- /backend/.sqlx/query-30141d915969c5d856ef98a52cfb29775d747273702512ff0e94c9f53b9cb6ae.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n DELETE FROM options\n WHERE name = $1\n ", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Text" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "30141d915969c5d856ef98a52cfb29775d747273702512ff0e94c9f53b9cb6ae" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-3357c72b39b5cfb154ed22ed2471e12555141ffcfaefa7c068b2f4c8f73c9c64.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT \n id,\n title,\n token,\n permissions AS \"permissions: Json\",\n active,\n (SELECT COUNT(*) FROM access_tokens_visits WHERE token_id = id AND visited_at > NOW() - INTERVAL '1 week') AS \"last_week_visits!\"\n FROM access_tokens\n WHERE id = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "token", 19 | "type_info": "Varchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "permissions: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "active", 29 | "type_info": "Bool" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "last_week_visits!", 34 | "type_info": "Int8" 35 | } 36 | ], 37 | "parameters": { 38 | "Left": [ 39 | "Uuid" 40 | ] 41 | }, 42 | "nullable": [ 43 | false, 44 | false, 45 | false, 46 | false, 47 | false, 48 | null 49 | ] 50 | }, 51 | "hash": "3357c72b39b5cfb154ed22ed2471e12555141ffcfaefa7c068b2f4c8f73c9c64" 52 | } 53 | -------------------------------------------------------------------------------- /backend/.sqlx/query-3566e1d5ed46ca2481e39c212945686666e172577e0b4276be88e694e9947c96.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n INSERT INTO tags (title, is_filter, is_primary_filter, \n filter_description, default_filter_status, fill_color, border_color)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n RETURNING id, title, is_filter, is_primary_filter, filter_description,\n default_filter_status, version, fill_color, border_color\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "is_filter", 19 | "type_info": "Bool" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "is_primary_filter", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "filter_description", 29 | "type_info": "Text" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "default_filter_status", 34 | "type_info": "Bool" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "fill_color", 44 | "type_info": "Varchar" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "border_color", 49 | "type_info": "Varchar" 50 | } 51 | ], 52 | "parameters": { 53 | "Left": [ 54 | "Varchar", 55 | "Bool", 56 | "Bool", 57 | "Text", 58 | "Bool", 59 | "Varchar", 60 | "Varchar" 61 | ] 62 | }, 63 | "nullable": [ 64 | false, 65 | false, 66 | false, 67 | false, 68 | true, 69 | false, 70 | false, 71 | false, 72 | false 73 | ] 74 | }, 75 | "hash": "3566e1d5ed46ca2481e39c212945686666e172577e0b4276be88e694e9947c96" 76 | } 77 | -------------------------------------------------------------------------------- /backend/.sqlx/query-3775dfc21e07361d7e0d4915fdb35c03403e04a2f1149f05ced03dbde368b1ed.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n WITH inserted AS (\n INSERT INTO entities (display_name, category_id, locations, data)\n VALUES ($1, $2, $3, $4)\n RETURNING *\n ) \n SELECT \n i.id, \n i.category_id, \n i.display_name, \n i.data,\n i.locations AS \"locations: Json>\",\n i.created_at,\n i.updated_at,\n array[]::uuid[] AS \"tags!\", \n c.family_id,\n f.entity_form AS \"entity_form: Json\", \n f.comment_form AS \"comment_form: Json\"\n FROM inserted i\n JOIN categories c ON c.id = i.category_id\n JOIN families f ON f.id = c.family_id\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "category_id", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "display_name", 19 | "type_info": "Text" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "data", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "locations: Json>", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "created_at", 34 | "type_info": "Timestamp" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "updated_at", 39 | "type_info": "Timestamp" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "tags!", 44 | "type_info": "UuidArray" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "family_id", 49 | "type_info": "Uuid" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "entity_form: Json", 54 | "type_info": "Jsonb" 55 | }, 56 | { 57 | "ordinal": 10, 58 | "name": "comment_form: Json", 59 | "type_info": "Jsonb" 60 | } 61 | ], 62 | "parameters": { 63 | "Left": [ 64 | "Text", 65 | "Uuid", 66 | "Jsonb", 67 | "Jsonb" 68 | ] 69 | }, 70 | "nullable": [ 71 | false, 72 | false, 73 | false, 74 | false, 75 | false, 76 | false, 77 | false, 78 | null, 79 | false, 80 | false, 81 | false 82 | ] 83 | }, 84 | "hash": "3775dfc21e07361d7e0d4915fdb35c03403e04a2f1149f05ced03dbde368b1ed" 85 | } 86 | -------------------------------------------------------------------------------- /backend/.sqlx/query-3860a60a914266bf4386fe9262af2896e70f65a23683155ac0551f253ad176b9.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n UPDATE families\n SET title = $2, entity_form = $3, comment_form = $4, sort_order = $5, version = $6\n WHERE id = $1\n RETURNING \n id,\n title,\n (SELECT hash FROM icons WHERE id = icon_id) as icon_hash,\n entity_form as \"entity_form: Json\",\n comment_form as \"comment_form: Json\",\n sort_order,\n version\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "icon_hash", 19 | "type_info": "Bpchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "entity_form: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "comment_form: Json", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "sort_order", 34 | "type_info": "Int4" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | } 41 | ], 42 | "parameters": { 43 | "Left": [ 44 | "Uuid", 45 | "Varchar", 46 | "Jsonb", 47 | "Jsonb", 48 | "Int4", 49 | "Int4" 50 | ] 51 | }, 52 | "nullable": [ 53 | false, 54 | false, 55 | null, 56 | false, 57 | false, 58 | false, 59 | false 60 | ] 61 | }, 62 | "hash": "3860a60a914266bf4386fe9262af2896e70f65a23683155ac0551f253ad176b9" 63 | } 64 | -------------------------------------------------------------------------------- /backend/.sqlx/query-3988d3372138cdb9d2be01bf08ec3a24517a2df8cce30b22f6ebfa45173b6cf3.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n INSERT INTO comments (entity_id, author, text, data)\n VALUES ($1, $2, $3, $4)\n RETURNING id, author, text, data, created_at, updated_at\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "author", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "text", 19 | "type_info": "Text" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "data", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "created_at", 29 | "type_info": "Timestamp" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "updated_at", 34 | "type_info": "Timestamp" 35 | } 36 | ], 37 | "parameters": { 38 | "Left": [ 39 | "Uuid", 40 | "Text", 41 | "Text", 42 | "Jsonb" 43 | ] 44 | }, 45 | "nullable": [ 46 | false, 47 | false, 48 | false, 49 | false, 50 | false, 51 | false 52 | ] 53 | }, 54 | "hash": "3988d3372138cdb9d2be01bf08ec3a24517a2df8cce30b22f6ebfa45173b6cf3" 55 | } 56 | -------------------------------------------------------------------------------- /backend/.sqlx/query-39b658e5d1fd32d876be8723c09a2c3b4f4006242e24fab776191f27fcab862b.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n DELETE FROM families\n WHERE id = $1\n ", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "39b658e5d1fd32d876be8723c09a2c3b4f4006242e24fab776191f27fcab862b" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-3c85c684a162418d90961456e5231bca0002f4e80da2bfcf62c4318c20be8f7f.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "SELECT id, name, password, is_admin, last_login FROM users WHERE name = $1", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "password", 19 | "type_info": "Text" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "is_admin", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "last_login", 29 | "type_info": "Timestamp" 30 | } 31 | ], 32 | "parameters": { 33 | "Left": [ 34 | "Text" 35 | ] 36 | }, 37 | "nullable": [ 38 | false, 39 | false, 40 | false, 41 | false, 42 | true 43 | ] 44 | }, 45 | "hash": "3c85c684a162418d90961456e5231bca0002f4e80da2bfcf62c4318c20be8f7f" 46 | } 47 | -------------------------------------------------------------------------------- /backend/.sqlx/query-3ec8dc8e90248fb05b43c65ed1944afe19b1248c62a022da4df181a93a11bd0b.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT \n id AS \"id!\",\n entity_id AS \"entity_id!\",\n category_id AS \"category_id!\",\n family_id AS \"family_id!\",\n display_name AS \"display_name!\",\n parents AS \"parents!: Json>\",\n locations AS \"locations!: Json>\",\n total_results AS \"total_results!\",\n total_pages AS \"total_pages!\",\n response_current_page AS \"response_current_page!\"\n FROM search_entities(\n $1,\n $2,\n $3,\n $4,\n $5,\n $6,\n $7,\n $8,\n $9,\n $10,\n $11,\n $12,\n $13,\n $14,\n $15,\n $16\n )\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id!", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "entity_id!", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "category_id!", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "family_id!", 24 | "type_info": "Uuid" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "display_name!", 29 | "type_info": "Text" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "parents!: Json>", 34 | "type_info": "Jsonb" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "locations!: Json>", 39 | "type_info": "Jsonb" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "total_results!", 44 | "type_info": "Int8" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "total_pages!", 49 | "type_info": "Int8" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "response_current_page!", 54 | "type_info": "Int8" 55 | } 56 | ], 57 | "parameters": { 58 | "Left": [ 59 | "Text", 60 | "Text", 61 | "Uuid", 62 | "Bool", 63 | "Bool", 64 | "UuidArray", 65 | "UuidArray", 66 | "UuidArray", 67 | "UuidArray", 68 | "Int8", 69 | "Int8", 70 | "UuidArray", 71 | "UuidArray", 72 | "UuidArray", 73 | "Bool", 74 | "Jsonb" 75 | ] 76 | }, 77 | "nullable": [ 78 | null, 79 | null, 80 | null, 81 | null, 82 | null, 83 | null, 84 | null, 85 | null, 86 | null, 87 | null 88 | ] 89 | }, 90 | "hash": "3ec8dc8e90248fb05b43c65ed1944afe19b1248c62a022da4df181a93a11bd0b" 91 | } 92 | -------------------------------------------------------------------------------- /backend/.sqlx/query-435644c7645eb37d5c869105ddbc4172230801ba506d4aae70c84f8ea8da8d22.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n WITH inserted AS (\n UPDATE comments\n SET \n entity_id = $2,\n author = $3,\n text = $4,\n data = $5,\n moderated = $6,\n version = $7\n WHERE id = $1\n RETURNING *\n )\n SELECT i.id, i.entity_id, i.author, i.text, i.data, i.created_at, i.updated_at, i.moderated, i.version, \n e.display_name AS entity_display_name, e.category_id AS entity_category_id\n FROM inserted i\n JOIN entities e \n ON e.id = entity_id\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "entity_id", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "author", 19 | "type_info": "Text" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "text", 24 | "type_info": "Text" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "data", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "created_at", 34 | "type_info": "Timestamp" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "updated_at", 39 | "type_info": "Timestamp" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "moderated", 44 | "type_info": "Bool" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "version", 49 | "type_info": "Int4" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "entity_display_name", 54 | "type_info": "Text" 55 | }, 56 | { 57 | "ordinal": 10, 58 | "name": "entity_category_id", 59 | "type_info": "Uuid" 60 | } 61 | ], 62 | "parameters": { 63 | "Left": [ 64 | "Uuid", 65 | "Uuid", 66 | "Text", 67 | "Text", 68 | "Jsonb", 69 | "Bool", 70 | "Int4" 71 | ] 72 | }, 73 | "nullable": [ 74 | false, 75 | false, 76 | false, 77 | false, 78 | false, 79 | false, 80 | false, 81 | false, 82 | false, 83 | false, 84 | false 85 | ] 86 | }, 87 | "hash": "435644c7645eb37d5c869105ddbc4172230801ba506d4aae70c84f8ea8da8d22" 88 | } 89 | -------------------------------------------------------------------------------- /backend/.sqlx/query-45761ad61a0aa459603cf56ea6e69f24cb7c02c3fece6708f6e4a220d636e9c9.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n WITH updated AS (\n UPDATE entities\n SET \n display_name = $2, \n category_id = $3, \n locations = $4, \n data = $5, \n hidden = $6, \n moderation_notes = $7, \n moderated = $8,\n version = $9\n WHERE id = $1\n RETURNING *\n )\n SELECT \n u.id,\n u.display_name,\n u.category_id,\n u.locations AS \"locations: Json>\",\n u.data,\n u.hidden,\n u.moderation_notes,\n u.moderated,\n u.created_at,\n u.updated_at,\n u.version,\n c.family_id,\n COALESCE(array(\n SELECT tag_id\n FROM entity_tags\n WHERE entity_id = u.id\n ), array[]::uuid[]) AS \"tags!\"\n FROM updated u\n JOIN categories c ON c.id = u.category_id\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "display_name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "category_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "locations: Json>", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "data", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "hidden", 34 | "type_info": "Bool" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "moderation_notes", 39 | "type_info": "Text" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "moderated", 44 | "type_info": "Bool" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "created_at", 49 | "type_info": "Timestamp" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "updated_at", 54 | "type_info": "Timestamp" 55 | }, 56 | { 57 | "ordinal": 10, 58 | "name": "version", 59 | "type_info": "Int4" 60 | }, 61 | { 62 | "ordinal": 11, 63 | "name": "family_id", 64 | "type_info": "Uuid" 65 | }, 66 | { 67 | "ordinal": 12, 68 | "name": "tags!", 69 | "type_info": "UuidArray" 70 | } 71 | ], 72 | "parameters": { 73 | "Left": [ 74 | "Uuid", 75 | "Text", 76 | "Uuid", 77 | "Jsonb", 78 | "Jsonb", 79 | "Bool", 80 | "Text", 81 | "Bool", 82 | "Int4" 83 | ] 84 | }, 85 | "nullable": [ 86 | false, 87 | false, 88 | false, 89 | false, 90 | false, 91 | false, 92 | true, 93 | false, 94 | false, 95 | false, 96 | false, 97 | false, 98 | null 99 | ] 100 | }, 101 | "hash": "45761ad61a0aa459603cf56ea6e69f24cb7c02c3fece6708f6e4a220d636e9c9" 102 | } 103 | -------------------------------------------------------------------------------- /backend/.sqlx/query-47dcef54f2d7b53f35623f5747b4a2dd89b45756b33e94879c2860ea5cb5f8df.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT\n COALESCE((\n WITH origins AS (\n SELECT DISTINCT(COALESCE(referrer, 'unknown')) AS referrer, COUNT(*) AS total\n FROM access_tokens_visits\n WHERE token_id = $1\n GROUP BY referrer\n )\n SELECT json_object_agg(referrer, total) FROM origins\n ), '{}') AS \"origins: JsonValue\",\n (\n WITH date_series AS (\n SELECT generate_series(\n NOW()::date - INTERVAL '30 days',\n NOW()::date,\n INTERVAL '1 day'\n )::date AS visit_date\n ),\n aggregated_visits AS (\n SELECT\n ds.visit_date,\n COALESCE(COUNT(atv.visited_at), 0) AS visit_count\n FROM\n date_series ds\n LEFT JOIN\n access_tokens_visits atv\n ON\n ds.visit_date = DATE(atv.visited_at) \n AND atv.token_id = $1\n GROUP BY\n ds.visit_date\n ORDER BY\n ds.visit_date\n )\n SELECT COALESCE(json_object_agg(\n TO_CHAR(visit_date, 'YYYY-MM-DD'),\n visit_count\n ), '{}') AS visits\n FROM aggregated_visits\n ) AS \"visits_30_days: JsonValue\"\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "origins: JsonValue", 9 | "type_info": "Json" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "visits_30_days: JsonValue", 14 | "type_info": "Json" 15 | } 16 | ], 17 | "parameters": { 18 | "Left": [ 19 | "Uuid" 20 | ] 21 | }, 22 | "nullable": [ 23 | null, 24 | null 25 | ] 26 | }, 27 | "hash": "47dcef54f2d7b53f35623f5747b4a2dd89b45756b33e94879c2860ea5cb5f8df" 28 | } 29 | -------------------------------------------------------------------------------- /backend/.sqlx/query-4de1c6da26f19d7f56049709bc786db9a4bc74d864a3f1184ea2ab0a4988e869.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT c.id, c.entity_id, c.author, c.text, c.data, c.created_at, c.updated_at, c.moderated, c.version,\n e.display_name AS entity_display_name, e.category_id AS entity_category_id\n FROM comments c\n JOIN entities e ON e.id = c.entity_id\n WHERE entity_id = $1\n ORDER BY created_at\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "entity_id", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "author", 19 | "type_info": "Text" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "text", 24 | "type_info": "Text" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "data", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "created_at", 34 | "type_info": "Timestamp" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "updated_at", 39 | "type_info": "Timestamp" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "moderated", 44 | "type_info": "Bool" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "version", 49 | "type_info": "Int4" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "entity_display_name", 54 | "type_info": "Text" 55 | }, 56 | { 57 | "ordinal": 10, 58 | "name": "entity_category_id", 59 | "type_info": "Uuid" 60 | } 61 | ], 62 | "parameters": { 63 | "Left": [ 64 | "Uuid" 65 | ] 66 | }, 67 | "nullable": [ 68 | false, 69 | false, 70 | false, 71 | false, 72 | false, 73 | false, 74 | false, 75 | false, 76 | false, 77 | false, 78 | false 79 | ] 80 | }, 81 | "hash": "4de1c6da26f19d7f56049709bc786db9a4bc74d864a3f1184ea2ab0a4988e869" 82 | } 83 | -------------------------------------------------------------------------------- /backend/.sqlx/query-50293c2e54af11d4c2a553e29b671cef087a159c6ee7182d8ca929ecb748f3b7.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "DELETE FROM users WHERE id = $1", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "50293c2e54af11d4c2a553e29b671cef087a159c6ee7182d8ca929ecb748f3b7" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-50ca7413465d5fc7facfcb8598fb02e6cf93bf1d75dd33eae15052bf7ba5829b.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n UPDATE categories\n SET title = $2, family_id = $3, default_status = $4, fill_color = $5, border_color = $6, version = $7\n WHERE id = $1\n RETURNING\n id,\n title,\n family_id,\n default_status,\n (SELECT hash FROM icons WHERE id = icon_id) AS icon_hash,\n fill_color,\n border_color,\n version\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "family_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "default_status", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "icon_hash", 29 | "type_info": "Bpchar" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "fill_color", 34 | "type_info": "Varchar" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "border_color", 39 | "type_info": "Varchar" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "version", 44 | "type_info": "Int4" 45 | } 46 | ], 47 | "parameters": { 48 | "Left": [ 49 | "Uuid", 50 | "Varchar", 51 | "Uuid", 52 | "Bool", 53 | "Varchar", 54 | "Varchar", 55 | "Int4" 56 | ] 57 | }, 58 | "nullable": [ 59 | false, 60 | false, 61 | false, 62 | false, 63 | null, 64 | false, 65 | false, 66 | false 67 | ] 68 | }, 69 | "hash": "50ca7413465d5fc7facfcb8598fb02e6cf93bf1d75dd33eae15052bf7ba5829b" 70 | } 71 | -------------------------------------------------------------------------------- /backend/.sqlx/query-51ea0fa88841a753ffa0b63f1771649ef335c8de49b73146e3a2831e71419b70.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT replace_tags_for_entity($1, $2)\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "replace_tags_for_entity", 9 | "type_info": "Void" 10 | } 11 | ], 12 | "parameters": { 13 | "Left": [ 14 | "Uuid", 15 | "UuidArray" 16 | ] 17 | }, 18 | "nullable": [ 19 | null 20 | ] 21 | }, 22 | "hash": "51ea0fa88841a753ffa0b63f1771649ef335c8de49b73146e3a2831e71419b70" 23 | } 24 | -------------------------------------------------------------------------------- /backend/.sqlx/query-5316deb346a27cddcdce842ef5da51857ea95762639d548ce36918dc2027d1d2.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT \n c.id AS category_id, \n c.family_id, \n COUNT(DISTINCT e.id) FILTER (WHERE e.moderated) AS \"moderated_entities_count!\", \n COUNT(DISTINCT e.id) FILTER (WHERE NOT e.moderated) AS \"unmoderated_entities_count!\", \n COUNT(cm.id) FILTER (WHERE cm.moderated) AS \"moderated_comments_count!\", \n COUNT(cm.id) FILTER (WHERE NOT cm.moderated) AS \"unmoderated_comments_count!\"\n FROM public.categories c\n JOIN public.entities e ON c.id = e.category_id\n LEFT JOIN public.comments cm ON e.id = cm.entity_id\n GROUP BY c.id, c.family_id\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "category_id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "family_id", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "moderated_entities_count!", 19 | "type_info": "Int8" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "unmoderated_entities_count!", 24 | "type_info": "Int8" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "moderated_comments_count!", 29 | "type_info": "Int8" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "unmoderated_comments_count!", 34 | "type_info": "Int8" 35 | } 36 | ], 37 | "parameters": { 38 | "Left": [] 39 | }, 40 | "nullable": [ 41 | false, 42 | false, 43 | null, 44 | null, 45 | null, 46 | null 47 | ] 48 | }, 49 | "hash": "5316deb346a27cddcdce842ef5da51857ea95762639d548ce36918dc2027d1d2" 50 | } 51 | -------------------------------------------------------------------------------- /backend/.sqlx/query-5c948122c3a1469040cf14571318ec26a5ff98d08011d3db5d6e41377a810b41.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "UPDATE users SET last_login = NOW() WHERE id = $1", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "5c948122c3a1469040cf14571318ec26a5ff98d08011d3db5d6e41377a810b41" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-5e6df0456cb4b90598b6f8d04bc86069d5c3558bd41481674ed50d6926d6d93e.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT families.id, families.title, (SELECT hash FROM icons WHERE id = families.icon_id) AS icon_hash,\n families.entity_form AS \"entity_form: Json\", \n families.comment_form AS \"comment_form: Json\",\n families.sort_order,\n families.version\n FROM families\n JOIN categories ON families.id = categories.family_id\n WHERE categories.id = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "icon_hash", 19 | "type_info": "Bpchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "entity_form: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "comment_form: Json", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "sort_order", 34 | "type_info": "Int4" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | } 41 | ], 42 | "parameters": { 43 | "Left": [ 44 | "Uuid" 45 | ] 46 | }, 47 | "nullable": [ 48 | false, 49 | false, 50 | null, 51 | false, 52 | false, 53 | false, 54 | false 55 | ] 56 | }, 57 | "hash": "5e6df0456cb4b90598b6f8d04bc86069d5c3558bd41481674ed50d6926d6d93e" 58 | } 59 | -------------------------------------------------------------------------------- /backend/.sqlx/query-5f5380734b3f0fa065b1830ccbacdf2ef38d24f4188b17858e79e0ff38464b69.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "SELECT upsert_row_icon($1, $2, $3, 'categories')", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "upsert_row_icon", 9 | "type_info": "Void" 10 | } 11 | ], 12 | "parameters": { 13 | "Left": [ 14 | "Uuid", 15 | "Bytea", 16 | "Text" 17 | ] 18 | }, 19 | "nullable": [ 20 | null 21 | ] 22 | }, 23 | "hash": "5f5380734b3f0fa065b1830ccbacdf2ef38d24f4188b17858e79e0ff38464b69" 24 | } 25 | -------------------------------------------------------------------------------- /backend/.sqlx/query-63ca3d01283df9eae426e9ccdc3d092272f7ea3b327f5b91db9bd07343d9a651.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT id, title, (SELECT hash FROM icons WHERE id = icon_id) as icon_hash, \n entity_form as \"entity_form: Json\", \n comment_form as \"comment_form: Json\",\n sort_order,\n version\n FROM families\n WHERE id = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "icon_hash", 19 | "type_info": "Bpchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "entity_form: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "comment_form: Json", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "sort_order", 34 | "type_info": "Int4" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | } 41 | ], 42 | "parameters": { 43 | "Left": [ 44 | "Uuid" 45 | ] 46 | }, 47 | "nullable": [ 48 | false, 49 | false, 50 | null, 51 | false, 52 | false, 53 | false, 54 | false 55 | ] 56 | }, 57 | "hash": "63ca3d01283df9eae426e9ccdc3d092272f7ea3b327f5b91db9bd07343d9a651" 58 | } 59 | -------------------------------------------------------------------------------- /backend/.sqlx/query-6e6b275479ea4753c86bd3c06c4b12c65e764824fc5a82d3ebd60d17bc667233.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "SELECT upsert_row_icon($1, $2, $3, 'families')", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "upsert_row_icon", 9 | "type_info": "Void" 10 | } 11 | ], 12 | "parameters": { 13 | "Left": [ 14 | "Uuid", 15 | "Bytea", 16 | "Text" 17 | ] 18 | }, 19 | "nullable": [ 20 | null 21 | ] 22 | }, 23 | "hash": "6e6b275479ea4753c86bd3c06c4b12c65e764824fc5a82d3ebd60d17bc667233" 24 | } 25 | -------------------------------------------------------------------------------- /backend/.sqlx/query-73773148b323ae294e78a121105d0f02f74cb91cc91ad87e33880e15996e7419.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT id, title, is_filter, is_primary_filter, filter_description, \n default_filter_status, version, fill_color, border_color\n FROM tags\n WHERE id = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "is_filter", 19 | "type_info": "Bool" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "is_primary_filter", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "filter_description", 29 | "type_info": "Text" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "default_filter_status", 34 | "type_info": "Bool" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "fill_color", 44 | "type_info": "Varchar" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "border_color", 49 | "type_info": "Varchar" 50 | } 51 | ], 52 | "parameters": { 53 | "Left": [ 54 | "Uuid" 55 | ] 56 | }, 57 | "nullable": [ 58 | false, 59 | false, 60 | false, 61 | false, 62 | true, 63 | false, 64 | false, 65 | false, 66 | false 67 | ] 68 | }, 69 | "hash": "73773148b323ae294e78a121105d0f02f74cb91cc91ad87e33880e15996e7419" 70 | } 71 | -------------------------------------------------------------------------------- /backend/.sqlx/query-774a79f460f88cbacfe0a7cd963ab3a073f83afc9eb0198fe440405e54687dc8.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n UPDATE access_tokens\n SET title = $2, token = $3, permissions = $4, active = $5\n WHERE id = $1\n RETURNING \n id,\n title,\n token,\n permissions AS \"permissions: Json\",\n active,\n (SELECT COUNT(*) FROM access_tokens_visits WHERE token_id = id AND visited_at > NOW() - INTERVAL '1 week') AS \"last_week_visits!\"\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "token", 19 | "type_info": "Varchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "permissions: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "active", 29 | "type_info": "Bool" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "last_week_visits!", 34 | "type_info": "Int8" 35 | } 36 | ], 37 | "parameters": { 38 | "Left": [ 39 | "Uuid", 40 | "Text", 41 | "Varchar", 42 | "Jsonb", 43 | "Bool" 44 | ] 45 | }, 46 | "nullable": [ 47 | false, 48 | false, 49 | false, 50 | false, 51 | false, 52 | null 53 | ] 54 | }, 55 | "hash": "774a79f460f88cbacfe0a7cd963ab3a073f83afc9eb0198fe440405e54687dc8" 56 | } 57 | -------------------------------------------------------------------------------- /backend/.sqlx/query-7b168898203679d14f1ccbcd1715ab2069b112d2df80ac40f80b3a63ee8ca92e.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "DELETE FROM icons WHERE id = (SELECT icon_id FROM categories WHERE id = $1)", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "7b168898203679d14f1ccbcd1715ab2069b112d2df80ac40f80b3a63ee8ca92e" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-7f9dad2abb0f3abd4339420e1709ed1553f8dfe420760910de8a2ab6bec3073f.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n DELETE FROM categories\n WHERE id = $1\n ", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "7f9dad2abb0f3abd4339420e1709ed1553f8dfe420760910de8a2ab6bec3073f" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-80d4efd69f7d05138746b053eaacf15818addf149b6c017ac8b56193d6a10245.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n INSERT INTO access_tokens_visits (token_id, referrer)\n VALUES ($1, $2)\n ", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid", 9 | "Text" 10 | ] 11 | }, 12 | "nullable": [] 13 | }, 14 | "hash": "80d4efd69f7d05138746b053eaacf15818addf149b6c017ac8b56193d6a10245" 15 | } 16 | -------------------------------------------------------------------------------- /backend/.sqlx/query-857475123f7d8c8793f2021635520ecaa0c912138ac77009f2461a228c106c7b.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT c.id, c.entity_id, c.author, c.text, c.data, c.created_at, c.updated_at, c.moderated, c.version,\n e.display_name AS entity_display_name, e.category_id AS entity_category_id\n FROM comments c\n JOIN entities e ON e.id = c.entity_id\n WHERE c.id = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "entity_id", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "author", 19 | "type_info": "Text" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "text", 24 | "type_info": "Text" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "data", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "created_at", 34 | "type_info": "Timestamp" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "updated_at", 39 | "type_info": "Timestamp" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "moderated", 44 | "type_info": "Bool" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "version", 49 | "type_info": "Int4" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "entity_display_name", 54 | "type_info": "Text" 55 | }, 56 | { 57 | "ordinal": 10, 58 | "name": "entity_category_id", 59 | "type_info": "Uuid" 60 | } 61 | ], 62 | "parameters": { 63 | "Left": [ 64 | "Uuid" 65 | ] 66 | }, 67 | "nullable": [ 68 | false, 69 | false, 70 | false, 71 | false, 72 | false, 73 | false, 74 | false, 75 | false, 76 | false, 77 | false, 78 | false 79 | ] 80 | }, 81 | "hash": "857475123f7d8c8793f2021635520ecaa0c912138ac77009f2461a228c106c7b" 82 | } 83 | -------------------------------------------------------------------------------- /backend/.sqlx/query-8690986b3442cedfce1de17432b38892be2fdfe2daee611e8b64970772acb17b.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n WITH inserted AS (\n INSERT INTO entities (display_name, category_id, locations, data, hidden, moderation_notes, moderated)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n RETURNING *\n )\n SELECT \n i.id,\n i.display_name,\n i.category_id,\n i.locations AS \"locations: Json>\",\n i.data,\n i.hidden,\n i.moderation_notes,\n i.moderated,\n i.created_at,\n i.updated_at,\n i.version,\n c.family_id,\n COALESCE(array(\n SELECT tag_id\n FROM entity_tags\n WHERE entity_id = i.id\n ), array[]::uuid[]) AS \"tags!\"\n FROM inserted i\n JOIN categories c ON c.id = i.category_id\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "display_name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "category_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "locations: Json>", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "data", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "hidden", 34 | "type_info": "Bool" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "moderation_notes", 39 | "type_info": "Text" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "moderated", 44 | "type_info": "Bool" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "created_at", 49 | "type_info": "Timestamp" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "updated_at", 54 | "type_info": "Timestamp" 55 | }, 56 | { 57 | "ordinal": 10, 58 | "name": "version", 59 | "type_info": "Int4" 60 | }, 61 | { 62 | "ordinal": 11, 63 | "name": "family_id", 64 | "type_info": "Uuid" 65 | }, 66 | { 67 | "ordinal": 12, 68 | "name": "tags!", 69 | "type_info": "UuidArray" 70 | } 71 | ], 72 | "parameters": { 73 | "Left": [ 74 | "Text", 75 | "Uuid", 76 | "Jsonb", 77 | "Jsonb", 78 | "Bool", 79 | "Text", 80 | "Bool" 81 | ] 82 | }, 83 | "nullable": [ 84 | false, 85 | false, 86 | false, 87 | false, 88 | false, 89 | false, 90 | true, 91 | false, 92 | false, 93 | false, 94 | false, 95 | false, 96 | null 97 | ] 98 | }, 99 | "hash": "8690986b3442cedfce1de17432b38892be2fdfe2daee611e8b64970772acb17b" 100 | } 101 | -------------------------------------------------------------------------------- /backend/.sqlx/query-93ea354a30d421bc27be9f28bfc99efd68d52f47025750e6663ea76ea529a3b7.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT\n id,\n title,\n family_id,\n default_status,\n (SELECT hash FROM icons WHERE id = icon_id) AS icon_hash,\n fill_color,\n border_color,\n version\n FROM categories\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "family_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "default_status", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "icon_hash", 29 | "type_info": "Bpchar" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "fill_color", 34 | "type_info": "Varchar" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "border_color", 39 | "type_info": "Varchar" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "version", 44 | "type_info": "Int4" 45 | } 46 | ], 47 | "parameters": { 48 | "Left": [] 49 | }, 50 | "nullable": [ 51 | false, 52 | false, 53 | false, 54 | false, 55 | null, 56 | false, 57 | false, 58 | false 59 | ] 60 | }, 61 | "hash": "93ea354a30d421bc27be9f28bfc99efd68d52f47025750e6663ea76ea529a3b7" 62 | } 63 | -------------------------------------------------------------------------------- /backend/.sqlx/query-9617c158d7c8cb409d9db78cfc77c783b9553ae0745c5f464dfb73557bca0f19.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT families.id, families.title, (SELECT hash FROM icons WHERE id = families.icon_id) AS icon_hash,\n families.entity_form AS \"entity_form: Json\", \n families.comment_form AS \"comment_form: Json\",\n families.sort_order,\n families.version\n FROM families\n JOIN categories ON families.id = categories.family_id\n JOIN entities ON categories.id = entities.category_id\n WHERE entities.id = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "icon_hash", 19 | "type_info": "Bpchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "entity_form: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "comment_form: Json", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "sort_order", 34 | "type_info": "Int4" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | } 41 | ], 42 | "parameters": { 43 | "Left": [ 44 | "Uuid" 45 | ] 46 | }, 47 | "nullable": [ 48 | false, 49 | false, 50 | null, 51 | false, 52 | false, 53 | false, 54 | false 55 | ] 56 | }, 57 | "hash": "9617c158d7c8cb409d9db78cfc77c783b9553ae0745c5f464dfb73557bca0f19" 58 | } 59 | -------------------------------------------------------------------------------- /backend/.sqlx/query-97070b0146d22a4b78469d02f6b842034eb8d76d219272349e7616fde7fac8ed.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "SELECT id, name, is_admin, last_login FROM users", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "is_admin", 19 | "type_info": "Bool" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "last_login", 24 | "type_info": "Timestamp" 25 | } 26 | ], 27 | "parameters": { 28 | "Left": [] 29 | }, 30 | "nullable": [ 31 | false, 32 | false, 33 | false, 34 | true 35 | ] 36 | }, 37 | "hash": "97070b0146d22a4b78469d02f6b842034eb8d76d219272349e7616fde7fac8ed" 38 | } 39 | -------------------------------------------------------------------------------- /backend/.sqlx/query-980dc595abe611c59bd1cc6d46dfb52a46b7fe1d830f37fdfd817121d7f1a56a.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT id, title, is_filter, is_primary_filter, filter_description,\n default_filter_status, version, fill_color, border_color\n FROM tags\n WHERE NOT (id = ANY($1))\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "is_filter", 19 | "type_info": "Bool" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "is_primary_filter", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "filter_description", 29 | "type_info": "Text" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "default_filter_status", 34 | "type_info": "Bool" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "fill_color", 44 | "type_info": "Varchar" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "border_color", 49 | "type_info": "Varchar" 50 | } 51 | ], 52 | "parameters": { 53 | "Left": [ 54 | "UuidArray" 55 | ] 56 | }, 57 | "nullable": [ 58 | false, 59 | false, 60 | false, 61 | false, 62 | true, 63 | false, 64 | false, 65 | false, 66 | false 67 | ] 68 | }, 69 | "hash": "980dc595abe611c59bd1cc6d46dfb52a46b7fe1d830f37fdfd817121d7f1a56a" 70 | } 71 | -------------------------------------------------------------------------------- /backend/.sqlx/query-a04146ed7909d632cdd53d1df7f3f84b546863d102dd9edcc34f8655aabffb36.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n INSERT INTO entities_entities (parent_id, child_id)\n VALUES ($1, $2)\n ", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid", 9 | "Uuid" 10 | ] 11 | }, 12 | "nullable": [] 13 | }, 14 | "hash": "a04146ed7909d632cdd53d1df7f3f84b546863d102dd9edcc34f8655aabffb36" 15 | } 16 | -------------------------------------------------------------------------------- /backend/.sqlx/query-a2215f2b60f0171eff8a5c1f5e3c70f1ef1912a68005f77837fc0a3336e30304.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT e.id, e.display_name, e.category_id, e.created_at, e.hidden,\n e.moderated, e.updated_at,\n COALESCE(\n (SELECT array_agg(t.tag_id) FROM entity_tags t WHERE t.entity_id = e.id), \n array[]::uuid[]\n ) AS \"tags!\"\n FROM entities e\n INNER JOIN entities_entities ee ON e.id = ee.child_id\n WHERE ee.parent_id = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "display_name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "category_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "created_at", 24 | "type_info": "Timestamp" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "hidden", 29 | "type_info": "Bool" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "moderated", 34 | "type_info": "Bool" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "updated_at", 39 | "type_info": "Timestamp" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "tags!", 44 | "type_info": "UuidArray" 45 | } 46 | ], 47 | "parameters": { 48 | "Left": [ 49 | "Uuid" 50 | ] 51 | }, 52 | "nullable": [ 53 | false, 54 | false, 55 | false, 56 | false, 57 | false, 58 | false, 59 | false, 60 | null 61 | ] 62 | }, 63 | "hash": "a2215f2b60f0171eff8a5c1f5e3c70f1ef1912a68005f77837fc0a3336e30304" 64 | } 65 | -------------------------------------------------------------------------------- /backend/.sqlx/query-a26eb8704bb81f1b60bb285994f6c79ba5f7c06c3f8fd00722f7e571727573f7.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n DELETE FROM access_tokens\n WHERE id = $1\n ", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "a26eb8704bb81f1b60bb285994f6c79ba5f7c06c3f8fd00722f7e571727573f7" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-a4ad29d1517628e943a7ae118deda6fdb8dbecf42873fd2ce76c825e60fcb7ec.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n INSERT INTO access_tokens (title, token, permissions, active)\n VALUES ($1, $2, $3, $4)\n RETURNING \n id,\n title,\n token, \n permissions AS \"permissions: Json\",\n active,\n 0 AS \"last_week_visits!\"\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "token", 19 | "type_info": "Varchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "permissions: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "active", 29 | "type_info": "Bool" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "last_week_visits!", 34 | "type_info": "Int4" 35 | } 36 | ], 37 | "parameters": { 38 | "Left": [ 39 | "Text", 40 | "Varchar", 41 | "Jsonb", 42 | "Bool" 43 | ] 44 | }, 45 | "nullable": [ 46 | false, 47 | false, 48 | false, 49 | false, 50 | false, 51 | null 52 | ] 53 | }, 54 | "hash": "a4ad29d1517628e943a7ae118deda6fdb8dbecf42873fd2ce76c825e60fcb7ec" 55 | } 56 | -------------------------------------------------------------------------------- /backend/.sqlx/query-a4d1f12942fa45b55e31dc8f35499723e0385de509d1f81eb37cb30a2e2d73e4.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT e.id,\n e.display_name,\n e.category_id,\n e.created_at,\n COALESCE(\n (SELECT array_agg(t.tag_id) FROM entity_tags t WHERE t.entity_id = e.id), \n array[]::uuid[]\n ) AS \"tags!\"\n FROM entities e\n INNER JOIN entities_entities ee ON e.id = ee.child_id\n WHERE ee.parent_id = $1 AND e.moderated AND NOT e.hidden\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "display_name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "category_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "created_at", 24 | "type_info": "Timestamp" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "tags!", 29 | "type_info": "UuidArray" 30 | } 31 | ], 32 | "parameters": { 33 | "Left": [ 34 | "Uuid" 35 | ] 36 | }, 37 | "nullable": [ 38 | false, 39 | false, 40 | false, 41 | false, 42 | null 43 | ] 44 | }, 45 | "hash": "a4d1f12942fa45b55e31dc8f35499723e0385de509d1f81eb37cb30a2e2d73e4" 46 | } 47 | -------------------------------------------------------------------------------- /backend/.sqlx/query-a9447d27feca9fbef65a6233465c3fab45e39a4193d222338506c348e9abff56.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT e.id, c.family_id, e.display_name, e.category_id, \n e.locations AS \"locations: Json>\", \n e.data, e.hidden, e.moderation_notes, e.moderated, \n e.created_at, e.updated_at, e.version,\n COALESCE(\n (SELECT array_agg(t.tag_id) FROM entity_tags t WHERE t.entity_id = e.id), \n array[]::uuid[]\n ) AS \"tags!\"\n FROM entities e\n INNER JOIN categories c ON e.category_id = c.id\n WHERE e.id = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "family_id", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "display_name", 19 | "type_info": "Text" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "category_id", 24 | "type_info": "Uuid" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "locations: Json>", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "data", 34 | "type_info": "Jsonb" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "hidden", 39 | "type_info": "Bool" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "moderation_notes", 44 | "type_info": "Text" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "moderated", 49 | "type_info": "Bool" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "created_at", 54 | "type_info": "Timestamp" 55 | }, 56 | { 57 | "ordinal": 10, 58 | "name": "updated_at", 59 | "type_info": "Timestamp" 60 | }, 61 | { 62 | "ordinal": 11, 63 | "name": "version", 64 | "type_info": "Int4" 65 | }, 66 | { 67 | "ordinal": 12, 68 | "name": "tags!", 69 | "type_info": "UuidArray" 70 | } 71 | ], 72 | "parameters": { 73 | "Left": [ 74 | "Uuid" 75 | ] 76 | }, 77 | "nullable": [ 78 | false, 79 | false, 80 | false, 81 | false, 82 | false, 83 | false, 84 | false, 85 | true, 86 | false, 87 | false, 88 | false, 89 | false, 90 | null 91 | ] 92 | }, 93 | "hash": "a9447d27feca9fbef65a6233465c3fab45e39a4193d222338506c348e9abff56" 94 | } 95 | -------------------------------------------------------------------------------- /backend/.sqlx/query-ae38d2ce78819912784f250c1d2418bcea27807509963d6a1d3dc69a8d67df41.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n INSERT INTO categories (title, family_id, default_status, fill_color, border_color)\n VALUES ($1, $2, $3, $4, $5)\n RETURNING\n id,\n title,\n family_id,\n default_status,\n (SELECT hash FROM icons WHERE id = icon_id) AS icon_hash,\n fill_color,\n border_color,\n version\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "family_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "default_status", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "icon_hash", 29 | "type_info": "Bpchar" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "fill_color", 34 | "type_info": "Varchar" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "border_color", 39 | "type_info": "Varchar" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "version", 44 | "type_info": "Int4" 45 | } 46 | ], 47 | "parameters": { 48 | "Left": [ 49 | "Varchar", 50 | "Uuid", 51 | "Bool", 52 | "Varchar", 53 | "Varchar" 54 | ] 55 | }, 56 | "nullable": [ 57 | false, 58 | false, 59 | false, 60 | false, 61 | null, 62 | false, 63 | false, 64 | false 65 | ] 66 | }, 67 | "hash": "ae38d2ce78819912784f250c1d2418bcea27807509963d6a1d3dc69a8d67df41" 68 | } 69 | -------------------------------------------------------------------------------- /backend/.sqlx/query-b0fdb9fa87e8ac1dc17e10a273355e4f20d9f920aa9fd0f7d5a216e5d4df9f2a.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT id, title, (SELECT hash FROM icons WHERE id = icon_id) as icon_hash,\n entity_form as \"entity_form: Json\", \n comment_form as \"comment_form: Json\",\n sort_order,\n version\n FROM families\n WHERE ($1 OR id = ANY($2)) AND NOT (id = ANY($3))\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "icon_hash", 19 | "type_info": "Bpchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "entity_form: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "comment_form: Json", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "sort_order", 34 | "type_info": "Int4" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | } 41 | ], 42 | "parameters": { 43 | "Left": [ 44 | "Bool", 45 | "UuidArray", 46 | "UuidArray" 47 | ] 48 | }, 49 | "nullable": [ 50 | false, 51 | false, 52 | null, 53 | false, 54 | false, 55 | false, 56 | false 57 | ] 58 | }, 59 | "hash": "b0fdb9fa87e8ac1dc17e10a273355e4f20d9f920aa9fd0f7d5a216e5d4df9f2a" 60 | } 61 | -------------------------------------------------------------------------------- /backend/.sqlx/query-b3f2cc59f7f9579cb89baf7bcd5b25c8a7edf07d0b8f1782117a97fcb097d6df.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "INSERT INTO options (name, value) VALUES ($1, $2) ON CONFLICT (name) DO UPDATE SET value = $2", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Varchar", 9 | "Jsonb" 10 | ] 11 | }, 12 | "nullable": [] 13 | }, 14 | "hash": "b3f2cc59f7f9579cb89baf7bcd5b25c8a7edf07d0b8f1782117a97fcb097d6df" 15 | } 16 | -------------------------------------------------------------------------------- /backend/.sqlx/query-b6ca4088314dfb1de406a59fd977b67123b085062e19f586a116868677338682.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n WITH inserted AS (\n INSERT INTO comments (entity_id, author, text, data, moderated)\n VALUES ($1, $2, $3, $4, $5)\n RETURNING *\n )\n SELECT i.id, i.entity_id, i.author, i.text, i.data, i.created_at, i.updated_at, i.moderated, i.version, \n display_name AS entity_display_name, category_id AS entity_category_id\n FROM inserted i\n JOIN entities e \n ON e.id = entity_id\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "entity_id", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "author", 19 | "type_info": "Text" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "text", 24 | "type_info": "Text" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "data", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "created_at", 34 | "type_info": "Timestamp" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "updated_at", 39 | "type_info": "Timestamp" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "moderated", 44 | "type_info": "Bool" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "version", 49 | "type_info": "Int4" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "entity_display_name", 54 | "type_info": "Text" 55 | }, 56 | { 57 | "ordinal": 10, 58 | "name": "entity_category_id", 59 | "type_info": "Uuid" 60 | } 61 | ], 62 | "parameters": { 63 | "Left": [ 64 | "Uuid", 65 | "Text", 66 | "Text", 67 | "Jsonb", 68 | "Bool" 69 | ] 70 | }, 71 | "nullable": [ 72 | false, 73 | false, 74 | false, 75 | false, 76 | false, 77 | false, 78 | false, 79 | false, 80 | false, 81 | false, 82 | false 83 | ] 84 | }, 85 | "hash": "b6ca4088314dfb1de406a59fd977b67123b085062e19f586a116868677338682" 86 | } 87 | -------------------------------------------------------------------------------- /backend/.sqlx/query-b96e044361f8664aef6dcf8ca00cf5d657286d7dba845a0551efc6677d40378d.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT e.id, c.family_id, e.category_id, e.display_name, e.data, e.created_at, e.updated_at,\n e.locations AS \"locations: Json>\",\n COALESCE(\n (SELECT array_agg(t.tag_id) FROM entity_tags t WHERE t.entity_id = e.id), \n array[]::uuid[]\n ) AS \"tags!\",\n f.entity_form AS \"entity_form: Json\",\n f.comment_form AS \"comment_form: Json\"\n FROM entities e\n INNER JOIN categories c ON e.category_id = c.id\n INNER JOIN families f ON c.family_id = f.id\n WHERE e.id = $1 AND e.moderated AND NOT e.hidden\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "family_id", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "category_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "display_name", 24 | "type_info": "Text" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "data", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "created_at", 34 | "type_info": "Timestamp" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "updated_at", 39 | "type_info": "Timestamp" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "locations: Json>", 44 | "type_info": "Jsonb" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "tags!", 49 | "type_info": "UuidArray" 50 | }, 51 | { 52 | "ordinal": 9, 53 | "name": "entity_form: Json", 54 | "type_info": "Jsonb" 55 | }, 56 | { 57 | "ordinal": 10, 58 | "name": "comment_form: Json", 59 | "type_info": "Jsonb" 60 | } 61 | ], 62 | "parameters": { 63 | "Left": [ 64 | "Uuid" 65 | ] 66 | }, 67 | "nullable": [ 68 | false, 69 | false, 70 | false, 71 | false, 72 | false, 73 | false, 74 | false, 75 | false, 76 | null, 77 | false, 78 | false 79 | ] 80 | }, 81 | "hash": "b96e044361f8664aef6dcf8ca00cf5d657286d7dba845a0551efc6677d40378d" 82 | } 83 | -------------------------------------------------------------------------------- /backend/.sqlx/query-cb733f3d3b968f2b2e3672b6b24db324e26f5082cdcee69c35c677660a94f532.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n UPDATE users \n SET name = $2, is_admin = $3 \n WHERE id = $1\n RETURNING\n id,\n name,\n is_admin,\n last_login\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "is_admin", 19 | "type_info": "Bool" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "last_login", 24 | "type_info": "Timestamp" 25 | } 26 | ], 27 | "parameters": { 28 | "Left": [ 29 | "Uuid", 30 | "Text", 31 | "Bool" 32 | ] 33 | }, 34 | "nullable": [ 35 | false, 36 | false, 37 | false, 38 | true 39 | ] 40 | }, 41 | "hash": "cb733f3d3b968f2b2e3672b6b24db324e26f5082cdcee69c35c677660a94f532" 42 | } 43 | -------------------------------------------------------------------------------- /backend/.sqlx/query-d0645eb40bf50d186b229cca83e2e4df322b902a68a86a4e82ee1fc47e031db6.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT\n id,\n title,\n token,\n permissions AS \"permissions: Json\",\n active,\n (SELECT COUNT(*) FROM access_tokens_visits WHERE token_id = id AND visited_at > NOW() - INTERVAL '1 week') AS \"last_week_visits!\"\n FROM access_tokens\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "token", 19 | "type_info": "Varchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "permissions: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "active", 29 | "type_info": "Bool" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "last_week_visits!", 34 | "type_info": "Int8" 35 | } 36 | ], 37 | "parameters": { 38 | "Left": [] 39 | }, 40 | "nullable": [ 41 | false, 42 | false, 43 | false, 44 | false, 45 | false, 46 | null 47 | ] 48 | }, 49 | "hash": "d0645eb40bf50d186b229cca83e2e4df322b902a68a86a4e82ee1fc47e031db6" 50 | } 51 | -------------------------------------------------------------------------------- /backend/.sqlx/query-d167f47a4e4b04f0616d205cd7c3e59619e9fa861a22334f27d852073f09adbf.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n INSERT INTO families (title, entity_form, comment_form, sort_order)\n VALUES ($1, $2, $3, $4)\n RETURNING \n id,\n title,\n (SELECT hash FROM icons WHERE id = icon_id) AS icon_hash,\n entity_form AS \"entity_form: Json\",\n comment_form AS \"comment_form: Json\",\n sort_order,\n version\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "icon_hash", 19 | "type_info": "Bpchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "entity_form: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "comment_form: Json", 29 | "type_info": "Jsonb" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "sort_order", 34 | "type_info": "Int4" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | } 41 | ], 42 | "parameters": { 43 | "Left": [ 44 | "Varchar", 45 | "Jsonb", 46 | "Jsonb", 47 | "Int4" 48 | ] 49 | }, 50 | "nullable": [ 51 | false, 52 | false, 53 | null, 54 | false, 55 | false, 56 | false, 57 | false 58 | ] 59 | }, 60 | "hash": "d167f47a4e4b04f0616d205cd7c3e59619e9fa861a22334f27d852073f09adbf" 61 | } 62 | -------------------------------------------------------------------------------- /backend/.sqlx/query-d4667242ba0c1d645f19ad1c560d2a6cca50b06f187095053888bee95c1fd9c1.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT e.id,\n e.display_name,\n e.category_id,\n e.created_at,\n COALESCE(\n (SELECT array_agg(t.tag_id) FROM entity_tags t WHERE t.entity_id = e.id), \n array[]::uuid[]\n ) AS \"tags!\"\n FROM entities e\n INNER JOIN entities_entities ee ON e.id = ee.parent_id\n WHERE ee.child_id = $1 AND e.moderated AND NOT e.hidden\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "display_name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "category_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "created_at", 24 | "type_info": "Timestamp" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "tags!", 29 | "type_info": "UuidArray" 30 | } 31 | ], 32 | "parameters": { 33 | "Left": [ 34 | "Uuid" 35 | ] 36 | }, 37 | "nullable": [ 38 | false, 39 | false, 40 | false, 41 | false, 42 | null 43 | ] 44 | }, 45 | "hash": "d4667242ba0c1d645f19ad1c560d2a6cca50b06f187095053888bee95c1fd9c1" 46 | } 47 | -------------------------------------------------------------------------------- /backend/.sqlx/query-d7a7af9e4da80ce587bb5e92896616e5907f0e256342b9ffb8600c4fa27cc18d.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n DELETE FROM tags\n WHERE id = $1\n ", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "d7a7af9e4da80ce587bb5e92896616e5907f0e256342b9ffb8600c4fa27cc18d" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-d7fa934a55e704afce7ad68af9502dc01b5ba5a467708225c63870f6b5eeeece.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT\n id,\n title,\n token,\n permissions AS \"permissions: Json\",\n active,\n 0 AS \"last_week_visits!\"\n FROM access_tokens\n WHERE token = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "token", 19 | "type_info": "Varchar" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "permissions: Json", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "active", 29 | "type_info": "Bool" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "last_week_visits!", 34 | "type_info": "Int4" 35 | } 36 | ], 37 | "parameters": { 38 | "Left": [ 39 | "Text" 40 | ] 41 | }, 42 | "nullable": [ 43 | false, 44 | false, 45 | false, 46 | false, 47 | false, 48 | null 49 | ] 50 | }, 51 | "hash": "d7fa934a55e704afce7ad68af9502dc01b5ba5a467708225c63870f6b5eeeece" 52 | } 53 | -------------------------------------------------------------------------------- /backend/.sqlx/query-d81da0cb8b8ee7f72bb84ecc104c96e274ecad13eda24e84a7aa7c856b8ca9e6.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n DELETE FROM comments\n WHERE id = $1\n ", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "d81da0cb8b8ee7f72bb84ecc104c96e274ecad13eda24e84a7aa7c856b8ca9e6" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-d8d142f7c2bb25eb449c391e3ca4f791f43d9188cac57b88d7839503a8e7b252.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "SELECT data, http_mime_type FROM icons WHERE hash = $1", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "data", 9 | "type_info": "Bytea" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "http_mime_type", 14 | "type_info": "Text" 15 | } 16 | ], 17 | "parameters": { 18 | "Left": [ 19 | "Bpchar" 20 | ] 21 | }, 22 | "nullable": [ 23 | false, 24 | false 25 | ] 26 | }, 27 | "hash": "d8d142f7c2bb25eb449c391e3ca4f791f43d9188cac57b88d7839503a8e7b252" 28 | } 29 | -------------------------------------------------------------------------------- /backend/.sqlx/query-dce78dca1b1ad3816445a421c9c2888d2c68c54545d35ba851681cb32842947b.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "SELECT name, value FROM options WHERE name = $1", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "name", 9 | "type_info": "Varchar" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "value", 14 | "type_info": "Jsonb" 15 | } 16 | ], 17 | "parameters": { 18 | "Left": [ 19 | "Text" 20 | ] 21 | }, 22 | "nullable": [ 23 | false, 24 | false 25 | ] 26 | }, 27 | "hash": "dce78dca1b1ad3816445a421c9c2888d2c68c54545d35ba851681cb32842947b" 28 | } 29 | -------------------------------------------------------------------------------- /backend/.sqlx/query-df114f7704654e85ae8a9433a91d1c4d3f603ec4992a6845c87b282bc870320e.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT e.id, e.display_name, e.category_id, e.created_at, e.hidden,\n e.moderated, e.updated_at,\n COALESCE(\n (SELECT array_agg(t.tag_id) FROM entity_tags t WHERE t.entity_id = e.id), \n array[]::uuid[]\n ) AS \"tags!\"\n FROM entities e\n INNER JOIN entities_entities ee ON e.id = ee.parent_id\n WHERE ee.child_id = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "display_name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "category_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "created_at", 24 | "type_info": "Timestamp" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "hidden", 29 | "type_info": "Bool" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "moderated", 34 | "type_info": "Bool" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "updated_at", 39 | "type_info": "Timestamp" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "tags!", 44 | "type_info": "UuidArray" 45 | } 46 | ], 47 | "parameters": { 48 | "Left": [ 49 | "Uuid" 50 | ] 51 | }, 52 | "nullable": [ 53 | false, 54 | false, 55 | false, 56 | false, 57 | false, 58 | false, 59 | false, 60 | null 61 | ] 62 | }, 63 | "hash": "df114f7704654e85ae8a9433a91d1c4d3f603ec4992a6845c87b282bc870320e" 64 | } 65 | -------------------------------------------------------------------------------- /backend/.sqlx/query-e1c14ad1400bb468668b8e3f8d3aeccc214f090685724e76b1ec6c92be7166bd.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n DELETE FROM entities\n WHERE id = $1\n ", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "e1c14ad1400bb468668b8e3f8d3aeccc214f090685724e76b1ec6c92be7166bd" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-e4bcd40211792477d6dff5d1d64d5b5b6ae3904d613c8285f750a8c6b5bd8e25.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n UPDATE tags\n SET title = $2, is_filter = $3, is_primary_filter = $4, filter_description = $5, \n default_filter_status = $6, version = $7, fill_color = $8, border_color = $9\n WHERE id = $1\n RETURNING id, title, is_filter, is_primary_filter, filter_description, \n default_filter_status, version, fill_color, border_color\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "is_filter", 19 | "type_info": "Bool" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "is_primary_filter", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "filter_description", 29 | "type_info": "Text" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "default_filter_status", 34 | "type_info": "Bool" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "fill_color", 44 | "type_info": "Varchar" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "border_color", 49 | "type_info": "Varchar" 50 | } 51 | ], 52 | "parameters": { 53 | "Left": [ 54 | "Uuid", 55 | "Varchar", 56 | "Bool", 57 | "Bool", 58 | "Text", 59 | "Bool", 60 | "Int4", 61 | "Varchar", 62 | "Varchar" 63 | ] 64 | }, 65 | "nullable": [ 66 | false, 67 | false, 68 | false, 69 | false, 70 | true, 71 | false, 72 | false, 73 | false, 74 | false 75 | ] 76 | }, 77 | "hash": "e4bcd40211792477d6dff5d1d64d5b5b6ae3904d613c8285f750a8c6b5bd8e25" 78 | } 79 | -------------------------------------------------------------------------------- /backend/.sqlx/query-e625c5d9489f670a20dd88f3383937a290bb75a1cd229cc03e840d84a6b37ba2.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "DELETE FROM icons WHERE id = (SELECT icon_id FROM families WHERE id = $1)", 4 | "describe": { 5 | "columns": [], 6 | "parameters": { 7 | "Left": [ 8 | "Uuid" 9 | ] 10 | }, 11 | "nullable": [] 12 | }, 13 | "hash": "e625c5d9489f670a20dd88f3383937a290bb75a1cd229cc03e840d84a6b37ba2" 14 | } 15 | -------------------------------------------------------------------------------- /backend/.sqlx/query-e767b125954189cb00b4f7661e1f758534cf0aec5b5bc0d4c550394d449c3a4d.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT id, title, is_filter, is_primary_filter, filter_description,\n default_filter_status, version, fill_color, border_color\n FROM tags\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "is_filter", 19 | "type_info": "Bool" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "is_primary_filter", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "filter_description", 29 | "type_info": "Text" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "default_filter_status", 34 | "type_info": "Bool" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "version", 39 | "type_info": "Int4" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "fill_color", 44 | "type_info": "Varchar" 45 | }, 46 | { 47 | "ordinal": 8, 48 | "name": "border_color", 49 | "type_info": "Varchar" 50 | } 51 | ], 52 | "parameters": { 53 | "Left": [] 54 | }, 55 | "nullable": [ 56 | false, 57 | false, 58 | false, 59 | false, 60 | true, 61 | false, 62 | false, 63 | false, 64 | false 65 | ] 66 | }, 67 | "hash": "e767b125954189cb00b4f7661e1f758534cf0aec5b5bc0d4c550394d449c3a4d" 68 | } 69 | -------------------------------------------------------------------------------- /backend/.sqlx/query-e92063f48832afff02878e598c3b59729ba8ff51fd774558cd26bf34e2957f1a.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT\n id,\n title,\n family_id,\n default_status,\n (SELECT hash FROM icons WHERE id = icon_id) AS icon_hash,\n fill_color,\n border_color,\n version\n FROM categories\n WHERE id = $1\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "title", 14 | "type_info": "Varchar" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "family_id", 19 | "type_info": "Uuid" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "default_status", 24 | "type_info": "Bool" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "icon_hash", 29 | "type_info": "Bpchar" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "fill_color", 34 | "type_info": "Varchar" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "border_color", 39 | "type_info": "Varchar" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "version", 44 | "type_info": "Int4" 45 | } 46 | ], 47 | "parameters": { 48 | "Left": [ 49 | "Uuid" 50 | ] 51 | }, 52 | "nullable": [ 53 | false, 54 | false, 55 | false, 56 | false, 57 | null, 58 | false, 59 | false, 60 | false 61 | ] 62 | }, 63 | "hash": "e92063f48832afff02878e598c3b59729ba8ff51fd774558cd26bf34e2957f1a" 64 | } 65 | -------------------------------------------------------------------------------- /backend/.sqlx/query-f611befc43dedf445e68c79972b1c4c7a02b3b0605bcf480fc99f6721891eb66.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n INSERT INTO users (name, password, is_admin) \n VALUES ($1, $2, $3) \n RETURNING\n id,\n name, \n is_admin,\n last_login\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "is_admin", 19 | "type_info": "Bool" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "last_login", 24 | "type_info": "Timestamp" 25 | } 26 | ], 27 | "parameters": { 28 | "Left": [ 29 | "Text", 30 | "Text", 31 | "Bool" 32 | ] 33 | }, 34 | "nullable": [ 35 | false, 36 | false, 37 | false, 38 | true 39 | ] 40 | }, 41 | "hash": "f611befc43dedf445e68c79972b1c4c7a02b3b0605bcf480fc99f6721891eb66" 42 | } 43 | -------------------------------------------------------------------------------- /backend/.sqlx/query-fbf5909594b8e0fc66c88fb8bf9f58fbd75eff94d127062e6d60684f8f82b8f7.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "SELECT id, name, is_admin, last_login FROM users WHERE id = $1", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "name", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "is_admin", 19 | "type_info": "Bool" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "last_login", 24 | "type_info": "Timestamp" 25 | } 26 | ], 27 | "parameters": { 28 | "Left": [ 29 | "Uuid" 30 | ] 31 | }, 32 | "nullable": [ 33 | false, 34 | false, 35 | false, 36 | true 37 | ] 38 | }, 39 | "hash": "fbf5909594b8e0fc66c88fb8bf9f58fbd75eff94d127062e6d60684f8f82b8f7" 40 | } 41 | -------------------------------------------------------------------------------- /backend/.sqlx/query-fd9c4f718c8d31bf339faf83d4c5922b4f0a4a79dd6da1bc2728a93811b27e6e.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT c.id, c.entity_id, e.display_name AS entity_display_name, e.category_id AS entity_category_id, c.created_at,\n c.author, c.moderated, c.updated_at\n FROM comments c\n INNER JOIN entities e ON c.entity_id = e.id\n WHERE NOT c.moderated\n ORDER BY created_at\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "entity_id", 14 | "type_info": "Uuid" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "entity_display_name", 19 | "type_info": "Text" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "entity_category_id", 24 | "type_info": "Uuid" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "created_at", 29 | "type_info": "Timestamp" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "author", 34 | "type_info": "Text" 35 | }, 36 | { 37 | "ordinal": 6, 38 | "name": "moderated", 39 | "type_info": "Bool" 40 | }, 41 | { 42 | "ordinal": 7, 43 | "name": "updated_at", 44 | "type_info": "Timestamp" 45 | } 46 | ], 47 | "parameters": { 48 | "Left": [] 49 | }, 50 | "nullable": [ 51 | false, 52 | false, 53 | false, 54 | false, 55 | false, 56 | false, 57 | false, 58 | false 59 | ] 60 | }, 61 | "hash": "fd9c4f718c8d31bf339faf83d4c5922b4f0a4a79dd6da1bc2728a93811b27e6e" 62 | } 63 | -------------------------------------------------------------------------------- /backend/.sqlx/query-ffed961cdeb582dadde70c53b98dcc677c2a045ebac44669ef8a02e7a67a3a30.json: -------------------------------------------------------------------------------- 1 | { 2 | "db_name": "PostgreSQL", 3 | "query": "\n SELECT id, author, text, data, created_at, updated_at\n FROM comments \n WHERE entity_id = $1 AND moderated\n ORDER BY created_at\n ", 4 | "describe": { 5 | "columns": [ 6 | { 7 | "ordinal": 0, 8 | "name": "id", 9 | "type_info": "Uuid" 10 | }, 11 | { 12 | "ordinal": 1, 13 | "name": "author", 14 | "type_info": "Text" 15 | }, 16 | { 17 | "ordinal": 2, 18 | "name": "text", 19 | "type_info": "Text" 20 | }, 21 | { 22 | "ordinal": 3, 23 | "name": "data", 24 | "type_info": "Jsonb" 25 | }, 26 | { 27 | "ordinal": 4, 28 | "name": "created_at", 29 | "type_info": "Timestamp" 30 | }, 31 | { 32 | "ordinal": 5, 33 | "name": "updated_at", 34 | "type_info": "Timestamp" 35 | } 36 | ], 37 | "parameters": { 38 | "Left": [ 39 | "Uuid" 40 | ] 41 | }, 42 | "nullable": [ 43 | false, 44 | false, 45 | false, 46 | false, 47 | false, 48 | false 49 | ] 50 | }, 51 | "hash": "ffed961cdeb582dadde70c53b98dcc677c2a045ebac44669ef8a02e7a67a3a30" 52 | } 53 | -------------------------------------------------------------------------------- /backend/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "safehaven" 3 | edition = "2021" 4 | 5 | [dependencies] 6 | sqlx = { version = "0.8", features = [ 7 | "runtime-tokio", 8 | "tls-rustls", 9 | "postgres", 10 | "chrono", 11 | "migrate", 12 | "uuid", 13 | "json", 14 | ] } 15 | serde = { version = "1", features = ["derive"] } 16 | serde_json = { version = "1", features = ["raw_value"] } 17 | serde_with = "3.8" 18 | rand = "0.8.5" 19 | uuid = { version = "1.8", features = ["serde", "v4"] } 20 | scrypt = "0.11" 21 | time = "0.3.36" 22 | chrono = { version = "0.4", features = ["serde"] } 23 | axum = { version = "0.7", features = ["macros", "multipart"] } 24 | cookie = "0.18.1" 25 | axum-extra = { version = "0.9", features = ["typed-header", "cookie"] } 26 | tokio = { version = "1.36", features = ["full"] } 27 | figment = { version = "0.10", features = ["toml", "env"] } 28 | jsonwebtoken = "9" 29 | tracing = "0.1" 30 | tower-http = { version = "0.5", features = ["fs", "trace", "cors"] } 31 | tracing-subscriber = { version = "0.3", features = ["env-filter"] } 32 | utoipa = { version = "4", features = ["axum_extras", "uuid", "chrono"] } 33 | clap = { version = "4", features = ["derive"] } 34 | clap_derive = { version = "4" } 35 | number_range = "0.3.2" 36 | crc32fast = "1.4.0" 37 | reqwest = { version = "0.12", features = [ 38 | "json", 39 | "rustls-tls", 40 | ], default-features = false } 41 | tiny-skia = { version = "0.11.4", features = ["png-format"] } 42 | resvg = "0.43" 43 | -------------------------------------------------------------------------------- /backend/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("cargo:rustc-env=SH_VERSION=main"); 3 | println!("cargo:rustc-env=SH_GITHASH=current"); 4 | } 5 | -------------------------------------------------------------------------------- /backend/migrations/20240608185144_util_functions.sql: -------------------------------------------------------------------------------- 1 | -- Icons upsert function 2 | CREATE OR REPLACE FUNCTION upsert_row_icon( 3 | p_row_id UUID, 4 | p_data BYTEA, 5 | p_http_mime_type TEXT, 6 | p_table_name TEXT 7 | ) RETURNS VOID AS $$ 8 | DECLARE 9 | v_icon_id UUID; 10 | v_query TEXT; 11 | BEGIN 12 | -- Check if the row already has an icon 13 | EXECUTE format('SELECT icon_id FROM %I WHERE id = $1', p_table_name) INTO v_icon_id USING p_row_id; 14 | 15 | IF v_icon_id IS NOT NULL THEN 16 | -- Update the existing icon 17 | UPDATE icons 18 | SET data = p_data, http_mime_type = p_http_mime_type 19 | WHERE id = v_icon_id; 20 | ELSE 21 | -- Insert a new icon 22 | INSERT INTO icons (data, http_mime_type) 23 | VALUES (p_data, p_http_mime_type) 24 | RETURNING id INTO v_icon_id; 25 | 26 | -- Update the row with the new icon_id 27 | EXECUTE format('UPDATE %I SET icon_id = $1 WHERE id = $2', p_table_name) USING v_icon_id, p_row_id; 28 | END IF; 29 | END; 30 | $$ LANGUAGE plpgsql; 31 | 32 | -- Replace tags for entity 33 | CREATE OR REPLACE FUNCTION replace_tags_for_entity( 34 | p_entity_id UUID, 35 | p_tags_ids UUID[] 36 | ) RETURNS VOID AS $$ 37 | BEGIN 38 | DELETE FROM entity_tags WHERE entity_id = p_entity_id; 39 | INSERT INTO entity_tags (entity_id, tag_id) 40 | SELECT p_entity_id, UNNEST(p_tags_ids); 41 | END; 42 | $$ LANGUAGE plpgsql; -------------------------------------------------------------------------------- /backend/src/api/admin/comments.rs: -------------------------------------------------------------------------------- 1 | use axum::{extract::Path, Json}; 2 | use uuid::Uuid; 3 | 4 | use crate::{ 5 | api::{AppError, AppJson, DbConn}, 6 | models::comment::{AdminComment, AdminListedComment, AdminNewOrUpdateComment}, 7 | }; 8 | 9 | #[utoipa::path( 10 | get, 11 | path = "/api/admin/comments/pending", 12 | responses( 13 | (status = 200, description = "List of pending comments", body = Vec), 14 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 15 | ) 16 | )] 17 | pub async fn admin_comments_pending( 18 | DbConn(mut conn): DbConn, 19 | ) -> Result>, AppError> { 20 | Ok(AppJson(AdminComment::pending(&mut conn).await?)) 21 | } 22 | 23 | #[utoipa::path( 24 | post, 25 | path = "/api/admin/comments", 26 | request_body = AdminNewOrUpdateComment, 27 | responses( 28 | (status = 200, description = "Comment created", body = AdminComment), 29 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 30 | ) 31 | )] 32 | pub async fn admin_comment_new( 33 | DbConn(mut conn): DbConn, 34 | Json(new_comment): Json, 35 | ) -> Result, AppError> { 36 | Ok(AppJson(AdminComment::new(new_comment, &mut conn).await?)) 37 | } 38 | 39 | #[utoipa::path( 40 | get, 41 | path = "/api/admin/comments/{id}", 42 | params( 43 | ("id" = Uuid, Path, description = "Comment identifier") 44 | ), 45 | responses( 46 | (status = 200, description = "Comment details", body = AdminComment), 47 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 48 | (status = 404, description = "Not found", body = ErrorResponse), 49 | ) 50 | )] 51 | pub async fn admin_comment_get( 52 | DbConn(mut conn): DbConn, 53 | Path(id): Path, 54 | ) -> Result, AppError> { 55 | Ok(AppJson(AdminComment::get(id, &mut conn).await?)) 56 | } 57 | 58 | #[utoipa::path( 59 | put, 60 | path = "/api/admin/comments/{id}", 61 | request_body = AdminNewOrUpdateComment, 62 | params( 63 | ("id" = Uuid, Path, description = "Comment identifier") 64 | ), 65 | responses( 66 | (status = 200, description = "Comment updated", body = AdminComment), 67 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 68 | (status = 404, description = "Not found", body = ErrorResponse), 69 | ) 70 | )] 71 | pub async fn admin_comment_update( 72 | DbConn(mut conn): DbConn, 73 | Path(id): Path, 74 | Json(updated_comment): Json, 75 | ) -> Result, AppError> { 76 | Ok(AppJson( 77 | AdminComment::update(id, updated_comment, &mut conn).await?, 78 | )) 79 | } 80 | 81 | #[utoipa::path( 82 | delete, 83 | path = "/api/admin/comments/{id}", 84 | params( 85 | ("id" = Uuid, Path, description = "Comment identifier") 86 | ), 87 | responses( 88 | (status = 200, description = "Comment deleted successfully"), 89 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 90 | (status = 404, description = "Not found", body = ErrorResponse), 91 | ) 92 | )] 93 | pub async fn admin_comment_delete( 94 | DbConn(mut conn): DbConn, 95 | Path(id): Path, 96 | ) -> Result, AppError> { 97 | AdminComment::delete(id, &mut conn).await?; 98 | Ok(AppJson(())) 99 | } 100 | -------------------------------------------------------------------------------- /backend/src/api/admin/statistics.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | api::{AppError, AppJson, DbConn}, 3 | models::statistics::{self, CountResult, HomePageStats}, 4 | }; 5 | 6 | #[utoipa::path( 7 | get, 8 | path = "/api/admin/stats", 9 | responses( 10 | (status = 200, description = "Stats for the home page", body = HomePageStats), 11 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 12 | ) 13 | )] 14 | pub async fn admin_home_stats( 15 | DbConn(mut conn): DbConn, 16 | ) -> Result, AppError> { 17 | Ok(AppJson(statistics::home_page_stats(&mut conn).await?)) 18 | } 19 | 20 | #[utoipa::path( 21 | get, 22 | path = "/api/admin/stats/count-comments-entities", 23 | responses( 24 | (status = 200, description = "Dicts of entities and comments counts by family and category id", body = (HashMap,HashMap),), 25 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 26 | ) 27 | )] 28 | pub async fn admin_count_comments_entities( 29 | DbConn(mut conn): DbConn, 30 | ) -> Result, AppError> { 31 | Ok(AppJson( 32 | statistics::count_comments_entities(&mut conn).await?, 33 | )) 34 | } 35 | -------------------------------------------------------------------------------- /backend/src/api/admin/tags.rs: -------------------------------------------------------------------------------- 1 | use axum::{extract::Path, Json}; 2 | use uuid::Uuid; 3 | 4 | use crate::{ 5 | api::{AppError, AppJson, DbConn}, 6 | models::tag::{NewOrUpdateTag, Tag}, 7 | }; 8 | 9 | #[utoipa::path( 10 | get, 11 | path = "/api/admin/tags", 12 | responses( 13 | (status = 200, description = "List of tags", body = Vec), 14 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 15 | ) 16 | )] 17 | pub async fn admin_tags_list(DbConn(mut conn): DbConn) -> Result>, AppError> { 18 | Ok(AppJson(Tag::list(&mut conn).await?)) 19 | } 20 | 21 | #[utoipa::path( 22 | post, 23 | path = "/api/admin/tags", 24 | request_body = NewOrUpdateTag, 25 | responses( 26 | (status = 200, description = "Tag created", body = Tag), 27 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 28 | ) 29 | )] 30 | pub async fn admin_tag_new( 31 | DbConn(mut conn): DbConn, 32 | Json(new_tag): Json, 33 | ) -> Result, AppError> { 34 | Ok(AppJson(Tag::new(new_tag, &mut conn).await?)) 35 | } 36 | 37 | #[utoipa::path( 38 | get, 39 | path = "/api/admin/tags/{id}", 40 | params( 41 | ("id" = Uuid, Path, description = "Tag identifier") 42 | ), 43 | responses( 44 | (status = 200, description = "Tag details", body = Tag), 45 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 46 | (status = 404, description = "Not found", body = ErrorResponse), 47 | ) 48 | )] 49 | pub async fn admin_tag_get( 50 | DbConn(mut conn): DbConn, 51 | Path(id): Path, 52 | ) -> Result, AppError> { 53 | Ok(AppJson(Tag::get(id, &mut conn).await?)) 54 | } 55 | 56 | #[utoipa::path( 57 | put, 58 | path = "/api/admin/tags/{id}", 59 | request_body = NewOrUpdateTag, 60 | params( 61 | ("id" = Uuid, Path, description = "Tag identifier") 62 | ), 63 | responses( 64 | (status = 200, description = "Tag updated", body = Tag), 65 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 66 | (status = 404, description = "Not found", body = ErrorResponse), 67 | ) 68 | )] 69 | pub async fn admin_tag_update( 70 | DbConn(mut conn): DbConn, 71 | Path(id): Path, 72 | Json(new_tag): Json, 73 | ) -> Result, AppError> { 74 | Ok(AppJson(Tag::update(id, new_tag, &mut conn).await?)) 75 | } 76 | 77 | #[utoipa::path( 78 | delete, 79 | path = "/api/admin/tags/{id}", 80 | params( 81 | ("id" = Uuid, Path, description = "Tag identifier") 82 | ), 83 | responses( 84 | (status = 200, description = "Tag deleted successfully"), 85 | (status = 401, description = "Invalid permissions", body = ErrorResponse), 86 | (status = 404, description = "Not found", body = ErrorResponse), 87 | ) 88 | )] 89 | pub async fn admin_tag_delete( 90 | DbConn(mut conn): DbConn, 91 | Path(id): Path, 92 | ) -> Result, AppError> { 93 | Tag::delete(id, &mut conn).await?; 94 | Ok(AppJson(())) 95 | } 96 | -------------------------------------------------------------------------------- /backend/src/config.rs: -------------------------------------------------------------------------------- 1 | use figment::{ 2 | providers::{Env, Format, Serialized, Toml}, 3 | Figment, 4 | }; 5 | 6 | use serde::{Deserialize, Serialize}; 7 | 8 | #[derive(Deserialize, Serialize, Clone)] 9 | pub struct SafeHavenConfig { 10 | /// Address to listen on 11 | pub listen_addr: String, 12 | /// Database configuration 13 | pub database: Database, 14 | /// Secret for JWT validation 15 | pub token_secret: String, 16 | /// Path to serve public files from 17 | pub serve_public_path: Option, 18 | /// Secure cookie flag 19 | pub secure_cookie: bool, 20 | } 21 | 22 | #[derive(Deserialize, Serialize, Clone)] 23 | /// Database configuration 24 | pub struct Database { 25 | /// Database URL ('postgresql://user:password@host/database') 26 | pub url: String, 27 | /// Database connection pool size (default to 5) 28 | pub pool_size: u32, 29 | /// Database connection timeout in seconds (default to 3) 30 | pub timeout: u64, 31 | } 32 | 33 | impl Default for SafeHavenConfig { 34 | fn default() -> Self { 35 | Self { 36 | listen_addr: "0.0.0.0:28669".to_string(), 37 | database: Database { 38 | url: "postgresql://postgres:postgres@localhost/safehaven".to_string(), 39 | pool_size: 5, 40 | timeout: 3, 41 | }, 42 | token_secret: "SecretForValidatingAngSigningTokens".to_string(), 43 | serve_public_path: None, 44 | secure_cookie: false, 45 | } 46 | } 47 | } 48 | 49 | pub fn load(config_path: &str) -> Result { 50 | Figment::from(Serialized::defaults(SafeHavenConfig::default())) 51 | .merge(Toml::file(config_path)) 52 | .merge(Env::prefixed("SH__").split("__")) 53 | .extract() 54 | } 55 | -------------------------------------------------------------------------------- /backend/src/helpers/deserializers.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Deserializer}; 2 | 3 | pub fn empty_string_is_invalid<'de, D>(deserializer: D) -> Result 4 | where 5 | D: Deserializer<'de>, 6 | { 7 | let s = String::deserialize(deserializer)?; 8 | if s.is_empty() { 9 | Err(serde::de::Error::custom("empty string is invalid")) 10 | } else { 11 | Ok(s) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /backend/src/helpers/hcaptcha.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | 3 | #[derive(Deserialize)] 4 | struct HCaptchaResponse { 5 | success: bool, 6 | 7 | #[serde(rename = "error-codes")] 8 | error_codes: Option>, 9 | } 10 | 11 | pub enum HCaptchaValidationError { 12 | NetworkError(), 13 | HCaptchaError(Vec), 14 | } 15 | 16 | pub async fn check_hcaptcha( 17 | client_response: String, 18 | secret: String, 19 | remote_ip: Option, 20 | ) -> Result { 21 | let client = reqwest::Client::new(); 22 | 23 | let mut form = vec![("response", client_response), ("secret", secret)]; 24 | 25 | if let Some(remote_ip) = remote_ip { 26 | form.push(("remoteip", remote_ip)); 27 | } 28 | 29 | let response = client 30 | .post("https://hcaptcha.com/siteverify") 31 | .form(&form) 32 | .send() 33 | .await 34 | .map_err(|_| HCaptchaValidationError::NetworkError())?; 35 | 36 | let response: HCaptchaResponse = response 37 | .json() 38 | .await 39 | .map_err(|_| HCaptchaValidationError::NetworkError())?; 40 | 41 | if response.success { 42 | Ok(true) 43 | } else { 44 | Err(HCaptchaValidationError::HCaptchaError( 45 | response.error_codes.unwrap_or_default(), 46 | )) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /backend/src/helpers/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod deserializers; 2 | pub mod hcaptcha; 3 | pub mod postgis_polygons; 4 | -------------------------------------------------------------------------------- /backend/src/helpers/postgis_polygons.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | use utoipa::ToSchema; 3 | 4 | #[derive(Serialize, Deserialize, Debug, Clone, ToSchema)] 5 | pub struct MultiPolygon(Vec>); 6 | 7 | impl MultiPolygon { 8 | pub fn to_polygon_string(&self, srid: Option) -> String { 9 | let polygons_str = self 10 | .0 11 | .iter() 12 | .map(|polygon| { 13 | let coords_str = polygon 14 | .iter() 15 | .map(|&(x, y)| format!("{} {}", x, y)) 16 | .collect::>() 17 | .join(", "); 18 | format!("({})", coords_str) 19 | }) 20 | .collect::>() 21 | .join("),("); 22 | 23 | match srid { 24 | Some(srid) => format!("SRID={};MULTIPOLYGON(({}))", srid, polygons_str), 25 | None => format!("MULTIPOLYGON(({}))", polygons_str), 26 | } 27 | } 28 | } 29 | 30 | #[cfg(test)] 31 | mod tests { 32 | use super::*; 33 | 34 | #[test] 35 | fn test_to_polygon_string() { 36 | let multi_polygon = MultiPolygon(vec![ 37 | vec![(30.0, 20.0), (45.0, 40.0), (10.0, 40.0), (30.0, 20.0)], 38 | vec![ 39 | (15.0, 5.0), 40 | (40.0, 10.0), 41 | (10.0, 20.0), 42 | (5.0, 10.0), 43 | (15.0, 5.0), 44 | ], 45 | ]); 46 | 47 | let expected_string = 48 | "MULTIPOLYGON(((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))"; 49 | assert_eq!(multi_polygon.to_polygon_string(None), expected_string); 50 | } 51 | 52 | #[test] 53 | fn test_to_polygon_string_with_srid() { 54 | let multi_polygon = MultiPolygon(vec![ 55 | vec![(30.0, 20.0), (45.0, 40.0), (10.0, 40.0), (30.0, 20.0)], 56 | vec![ 57 | (15.0, 5.0), 58 | (40.0, 10.0), 59 | (10.0, 20.0), 60 | (5.0, 10.0), 61 | (15.0, 5.0), 62 | ], 63 | ]); 64 | 65 | let expected_string = 66 | "SRID=3857;MULTIPOLYGON(((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))"; 67 | assert_eq!(multi_polygon.to_polygon_string(Some(3857)), expected_string); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /backend/src/models/icon.rs: -------------------------------------------------------------------------------- 1 | use sqlx::PgConnection; 2 | use uuid::Uuid; 3 | 4 | use crate::api::AppError; 5 | 6 | pub struct Icon { 7 | pub data: Vec, 8 | pub http_mime_type: String, 9 | } 10 | 11 | impl Icon { 12 | pub async fn get(hash: String, conn: &mut PgConnection) -> Result { 13 | let icon = sqlx::query_as!( 14 | Icon, 15 | r#"SELECT data, http_mime_type FROM icons WHERE hash = $1"#, 16 | hash 17 | ) 18 | .fetch_one(conn) 19 | .await 20 | .map_err(AppError::Database)?; 21 | 22 | Ok(icon) 23 | } 24 | 25 | pub async fn delete_for_family( 26 | family_id: Uuid, 27 | conn: &mut PgConnection, 28 | ) -> Result<(), AppError> { 29 | sqlx::query!( 30 | r#"DELETE FROM icons WHERE id = (SELECT icon_id FROM families WHERE id = $1)"#, 31 | family_id 32 | ) 33 | .execute(conn) 34 | .await 35 | .map_err(AppError::Database)?; 36 | 37 | Ok(()) 38 | } 39 | 40 | pub async fn delete_for_category( 41 | category_id: Uuid, 42 | conn: &mut PgConnection, 43 | ) -> Result<(), AppError> { 44 | sqlx::query!( 45 | r#"DELETE FROM icons WHERE id = (SELECT icon_id FROM categories WHERE id = $1)"#, 46 | category_id 47 | ) 48 | .execute(conn) 49 | .await 50 | .map_err(AppError::Database)?; 51 | 52 | Ok(()) 53 | } 54 | 55 | pub async fn upsert_family( 56 | family_id: Uuid, 57 | data: Vec, 58 | http_mime_type: String, 59 | conn: &mut PgConnection, 60 | ) -> Result<(), AppError> { 61 | sqlx::query!( 62 | r#"SELECT upsert_row_icon($1, $2, $3, 'families')"#, 63 | family_id, 64 | data, 65 | http_mime_type 66 | ) 67 | .execute(conn) 68 | .await 69 | .map_err(AppError::Database)?; 70 | 71 | Ok(()) 72 | } 73 | 74 | pub async fn upsert_category( 75 | category_id: Uuid, 76 | data: Vec, 77 | http_mime_type: String, 78 | conn: &mut PgConnection, 79 | ) -> Result<(), AppError> { 80 | sqlx::query!( 81 | r#"SELECT upsert_row_icon($1, $2, $3, 'categories')"#, 82 | category_id, 83 | data, 84 | http_mime_type 85 | ) 86 | .execute(conn) 87 | .await 88 | .map_err(AppError::Database)?; 89 | 90 | Ok(()) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /backend/src/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod access_token; 2 | pub mod category; 3 | pub mod comment; 4 | pub mod entity; 5 | pub mod entity_cache; 6 | pub mod family; 7 | pub mod icon; 8 | pub mod options; 9 | pub mod statistics; 10 | pub mod tag; 11 | pub mod user; 12 | -------------------------------------------------------------------------------- /container_release: -------------------------------------------------------------------------------- 1 | latest -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "fenix": { 4 | "inputs": { 5 | "nixpkgs": [ 6 | "nixpkgs" 7 | ], 8 | "rust-analyzer-src": "rust-analyzer-src" 9 | }, 10 | "locked": { 11 | "lastModified": 1752993983, 12 | "narHash": "sha256-3YKCySMNhFDdHbFiRS4QbEwk0U5l42NMD1scDtniESY=", 13 | "owner": "nix-community", 14 | "repo": "fenix", 15 | "rev": "62105e0745d7450976b26dbd1497b8cbe15eb9ff", 16 | "type": "github" 17 | }, 18 | "original": { 19 | "owner": "nix-community", 20 | "repo": "fenix", 21 | "type": "github" 22 | } 23 | }, 24 | "flake-utils": { 25 | "inputs": { 26 | "systems": "systems" 27 | }, 28 | "locked": { 29 | "lastModified": 1731533236, 30 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 31 | "owner": "numtide", 32 | "repo": "flake-utils", 33 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 34 | "type": "github" 35 | }, 36 | "original": { 37 | "owner": "numtide", 38 | "repo": "flake-utils", 39 | "type": "github" 40 | } 41 | }, 42 | "nixpkgs": { 43 | "locked": { 44 | "lastModified": 1752950548, 45 | "narHash": "sha256-NS6BLD0lxOrnCiEOcvQCDVPXafX1/ek1dfJHX1nUIzc=", 46 | "owner": "NixOS", 47 | "repo": "nixpkgs", 48 | "rev": "c87b95e25065c028d31a94f06a62927d18763fdf", 49 | "type": "github" 50 | }, 51 | "original": { 52 | "owner": "NixOS", 53 | "ref": "nixos-unstable", 54 | "repo": "nixpkgs", 55 | "type": "github" 56 | } 57 | }, 58 | "root": { 59 | "inputs": { 60 | "fenix": "fenix", 61 | "flake-utils": "flake-utils", 62 | "nixpkgs": "nixpkgs" 63 | } 64 | }, 65 | "rust-analyzer-src": { 66 | "flake": false, 67 | "locked": { 68 | "lastModified": 1752913824, 69 | "narHash": "sha256-kRpDlijAr4p5VmcPSRw2mfhaBZ4cE3EDWzqLDIbASgA=", 70 | "owner": "rust-lang", 71 | "repo": "rust-analyzer", 72 | "rev": "ed193af36937d2fd4bb14a815ec589875c5c7304", 73 | "type": "github" 74 | }, 75 | "original": { 76 | "owner": "rust-lang", 77 | "ref": "nightly", 78 | "repo": "rust-analyzer", 79 | "type": "github" 80 | } 81 | }, 82 | "systems": { 83 | "locked": { 84 | "lastModified": 1681028828, 85 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 86 | "owner": "nix-systems", 87 | "repo": "default", 88 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 89 | "type": "github" 90 | }, 91 | "original": { 92 | "owner": "nix-systems", 93 | "repo": "default", 94 | "type": "github" 95 | } 96 | } 97 | }, 98 | "root": "root", 99 | "version": 7 100 | } 101 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | 26 | # Generated from the backend openapi 27 | lib/api.d.ts 28 | 29 | -------------------------------------------------------------------------------- /frontend/app.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 53 | -------------------------------------------------------------------------------- /frontend/assets/main.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | #__nuxt { 4 | height: 100%; 5 | width: 100%; 6 | margin: 0; 7 | padding: 0; 8 | } 9 | 10 | /* Background Colors */ 11 | .lilac-bg { 12 | background-color: #e0a2ff; 13 | } 14 | 15 | .hot-pink-bg { 16 | background-color: #e86ba7; 17 | } 18 | 19 | .poudre-bg { 20 | background-color: #f7eaff; 21 | } 22 | 23 | .coco-bg { 24 | background-color: #ffffff; 25 | } 26 | 27 | /* Text Colors */ 28 | .lilac-text { 29 | color: #e0a2ff; 30 | } 31 | 32 | .hot-pink-text { 33 | color: #e86ba7; 34 | } 35 | 36 | .poudre-text { 37 | color: #f7eaff; 38 | } 39 | 40 | .coco-text { 41 | color: #ffffff; 42 | } 43 | -------------------------------------------------------------------------------- /frontend/assets/richtext.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | .rich-text-content h1 { 7 | @apply text-3xl font-bold mb-2; 8 | } 9 | 10 | .rich-text-content h2 { 11 | @apply text-2xl font-bold mb-2; 12 | } 13 | 14 | .rich-text-content h3 { 15 | @apply text-xl font-bold mb-2; 16 | } 17 | 18 | .rich-text-content h4 { 19 | @apply text-lg font-bold mb-2; 20 | } 21 | 22 | .rich-text-content h5 { 23 | @apply text-base font-bold mb-2; 24 | } 25 | 26 | .rich-text-content h6 { 27 | @apply text-sm font-bold mb-1; 28 | } 29 | 30 | .rich-text-content p { 31 | @apply mb-4 leading-tight; 32 | } 33 | 34 | .rich-text-content ul { 35 | @apply list-disc pl-5 mb-4; 36 | } 37 | 38 | .rich-text-content a { 39 | @apply underline text-blue-600 hover:text-blue-800; 40 | } 41 | 42 | .rich-text-content em, 43 | .rich-text-content i { 44 | @apply italic; 45 | } 46 | 47 | .rich-text-content strong, 48 | .rich-text-content b { 49 | @apply font-bold; 50 | } 51 | 52 | .rich-text-content u { 53 | @apply underline; 54 | } 55 | 56 | .rich-text-content s { 57 | @apply line-through; 58 | } 59 | 60 | .rich-text-content q, 61 | .rich-text-content blockquote { 62 | @apply border-l-4 border-gray-300 pl-2 italic; 63 | } 64 | } -------------------------------------------------------------------------------- /frontend/components/AppIcon.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 82 | 83 | 101 | -------------------------------------------------------------------------------- /frontend/components/CategoryTag.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 26 | -------------------------------------------------------------------------------- /frontend/components/CommentsDisplayer.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 69 | -------------------------------------------------------------------------------- /frontend/components/DisplayedTag.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 31 | -------------------------------------------------------------------------------- /frontend/components/NominatimPicker.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 76 | -------------------------------------------------------------------------------- /frontend/components/RequiredIndicator.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /frontend/components/SingleEntityMap.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 85 | 86 | 93 | -------------------------------------------------------------------------------- /frontend/components/StartPopup.vue: -------------------------------------------------------------------------------- 1 | 2 | 44 | 45 | 68 | -------------------------------------------------------------------------------- /frontend/components/admin/UserAvatar.vue: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 26 | -------------------------------------------------------------------------------- /frontend/components/admin/input/ColorField.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 44 | -------------------------------------------------------------------------------- /frontend/components/admin/input/NumberField.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 34 | -------------------------------------------------------------------------------- /frontend/components/admin/input/PolicyPermissionField.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 58 | -------------------------------------------------------------------------------- /frontend/components/admin/input/SwitchField.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 29 | -------------------------------------------------------------------------------- /frontend/components/admin/input/TextField.vue: -------------------------------------------------------------------------------- 1 |