basic project files

This commit is contained in:
2026-06-19 23:47:07 -07:00
parent e3e520f7a9
commit cef6b487cd
14 changed files with 2400 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
api/node_modules
api/dist
web/node_modules
web/dist
dist
npm-debug.log
node_modules
docs
/now.*
/*.now.*
**/now.*
+11
View File
@@ -0,0 +1,11 @@
env:
browser: true
es2021: true
node: true
extends:
- prettier
overrides: []
parserOptions:
ecmaVersion: latest
sourceType: module
rules: {}
+112
View File
@@ -0,0 +1,112 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories + files
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
.env.production
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
app
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
db/sapassword.env
.env.development
# DB Data
db/data
/db_dumps
+19
View File
@@ -0,0 +1,19 @@
# .prettierrc or .prettierrc.yaml
$schema: "https://json.schemastore.org/prettierrc"
embeddedLanguageFormatting: "auto"
trailingComma: "es5"
tabWidth: 2
semi: false
singleQuote: false
singleAttributePerLine: true
useTabs: false
endOfLine: "auto"
printWidth: 100
plugins:
- prettier-plugin-embed
- prettier-plugin-sql
overrides:
- files: "*.sql"
options:
language: "tsql"
paramTypes: "{ named: [':'] }"
+2
View File
@@ -0,0 +1,2 @@
nodejs 20.10.0
ruby 3.2.2
+22
View File
@@ -0,0 +1,22 @@
{
"eslint.workingDirectories": ["./api", "./web"],
"eslint.validate": ["javascript", "typescript", "vue"],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"prettier.configPath": ".prettierrc.yaml",
"prettier.requireConfig": true,
"prettier.resolveGlobalModules": true,
"js/ts.preferences.importModuleSpecifier": "non-relative",
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
+77
View File
@@ -0,0 +1,77 @@
# Stage 0 - base node customizations
FROM node:20.19.4-alpine3.22 AS base-node
RUN npm install -g npm@10.2.5
# Stage 1 - api build - requires development environment because typescript
FROM base-node AS api-build-stage
ENV NODE_ENV=development
WORKDIR /usr/src/api
COPY api/package*.json ./
COPY api/tsconfig*.json ./
RUN npm install
COPY api ./
RUN npm run build
# Copy html files, remove once we are using Vite for build process
COPY api/src/templates ./dist/templates
# Stage 2 - web build - requires development environment to install vue-cli-service
FROM base-node AS web-build-stage
ENV NODE_ENV=development
WORKDIR /usr/src/web
COPY web/package*.json ./
COPY web/tsconfig*.json ./
COPY web/vite.config.js ./
RUN npm install
COPY web ./
# Switching to production mode for build environment.
ENV NODE_ENV=production
RUN npm run build
# Stage 3 - production setup
FROM base-node
ARG RELEASE_TAG
ARG GIT_COMMIT_HASH
ENV RELEASE_TAG=${RELEASE_TAG}
ENV GIT_COMMIT_HASH=${GIT_COMMIT_HASH}
# Persists TZ=UTC effect after container build and into container run
# Ensures dates/times are consistently formated as UTC
# Conversion to local time should happen in the UI
ENV TZ=UTC
ENV NODE_ENV=production
USER node
WORKDIR /home/node/app
RUN chown -R node:node /home/node/app
COPY --from=api-build-stage --chown=node:node /usr/src/api/package*.json ./
RUN npm install && npm cache clean --force --loglevel=error
COPY --from=api-build-stage --chown=node:node /usr/src/api/dist ./dist/
COPY --from=web-build-stage --chown=node:node /usr/src/web/dist ./dist/web/
RUN echo "RELEASE_TAG=${RELEASE_TAG}" >> VERSION
RUN echo "GIT_COMMIT_HASH=${GIT_COMMIT_HASH}" >> VERSION
EXPOSE 3000
COPY --from=api-build-stage --chown=node:node /usr/src/api/bin/boot-app.sh ./bin/
RUN chmod +x ./bin/boot-app.sh
CMD ["./bin/boot-app.sh"]
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+72
View File
@@ -0,0 +1,72 @@
# `dev` command documentation
## `dev` Command
The `dev` command is a helper for using docker compose.
For example, you can run a sql script via
```bash
dev sqlcmd -i ./data/funding_submission_lines.sql
```
assuming the file is located at `/db/data/funding_submission_lines.sql`
Note that the `dev` command uses the `db` service, and so only has access to folders under the top-level `db` directory.
## Set up `dev` command
The `dev` command vastly simplifies development using docker compose. It only requires `ruby`; however, `direnv` and `asdf` will make it easier to use.
It's simply a wrapper around docker compose with the ability to quickly add custom helpers.
All commands are just strings joined together, so it's easy to add new commmands. `dev` prints out each command that it runs, so that you can run the command manually to debug it, or just so you learn some docker compose syntax as you go.
1. (optional) Install `asdf` as seen in <https://asdf-vm.com/guide/getting-started.html>.
e.g. for Linux
```bash
apt install curl git
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.12.0
echo '
# asdf
. "$HOME/.asdf/asdf.sh"
. "$HOME/.asdf/completions/asdf.bash"
' >> ~/.bashrc
```
2. Install `ruby` via `asdf` as seen here <https://github.com/asdf-vm/asdf-ruby>, or using whatever custom Ruby install method works for your platform.
e.g. for Linux
```bash
asdf plugin add ruby https://github.com/asdf-vm/asdf-ruby.git
# install version from .tool-versions file
asdf install ruby
asdf reshim ruby
```
You will now be able to run the `./bin/dev` command.
3. (optional) Install [direnv](https://direnv.net/) and create an `.envrc` with
```bash
#!/usr/bin/env bash
PATH_add bin
```
and then run `direnv allow`.
You will now be able to do `dev xxx` instead ov `./bin/dev xxx`.
## Extras
If you want to take over a directory or file in Linux you can use `dev ownit <path-to-directory-or-file>`.
If you are on Windows or Mac, and you want that to work, you should implement it in the `bin/dev` file. You might never actually need to take ownership of anything, so this might not be relevant to you.
Executable
+295
View File
@@ -0,0 +1,295 @@
#!/usr/bin/env ruby
class DevHelper
# Support dashes in command names
COMMAND_TO_METHOD = {
"ts-node" => :ts_node,
"check-types" => :check_types,
"bash-completions" => :bash_completions,
"plantuml-to-png" => :plantuml_to_png,
}
METHOD_TO_COMMAND = COMMAND_TO_METHOD.invert
REPLACE_PROCESS = "replace_process"
WAIT_FOR_PROCESS = "wait_for_process"
# External Interface
def self.call(*args)
new.call(*args)
end
# Core logic
def call(*args, **kwargs)
command = args[0]
method = COMMAND_TO_METHOD.fetch(command, command)
if args.length.positive? && respond_to?(method)
public_send(method, *args.drop(1), **kwargs)
else
compose(*args, **kwargs)
end
end
def compose(*args, **kwargs)
command = compose_command(*args, **kwargs)
puts "Running: #{command}" unless kwargs[:slient]
case kwargs[:execution_mode]
when WAIT_FOR_PROCESS
wait_for_process_with_logging(command)
else
exec(command)
end
end
# Primary command wrappers
def build(*args, **kwargs)
compose(%w[build], *args, **kwargs)
end
def compile(*args, **kwargs)
run(*%w[api npm run build], execution_mode: WAIT_FOR_PROCESS)
exit($?.exitstatus) unless $?.success?
run(*%w[web npm run build])
end
def up(*args, **kwargs)
compose(*%w[up --remove-orphans], *args, **kwargs)
end
def down(*args, **kwargs)
compose(*%w[down --remove-orphans], *args, **kwargs)
end
def logs(*args, **kwargs)
compose(*%w[logs -f], *args, **kwargs)
end
def run(*args, **kwargs)
compose(*%w[run --rm], *args, **kwargs)
end
def ps(*args, **kwargs)
compose(*%w[ps], *args, **kwargs)
end
# Custom helpers
def api(*args, **kwargs)
run(*%w[api], *args, **kwargs)
end
def web(*args, **kwargs)
run(*%w[web], *args, **kwargs)
end
def check_types(*args, **kwargs)
run(*%w[api npm run check-types], *args, **kwargs)
end
def test(*args, **kwargs)
service = args[0]
if service == "api"
test_api(*args.drop(1), **kwargs)
elsif service == "web"
test_web(*args.drop(1), **kwargs)
else
test_api(*args, **kwargs)
end
end
def test_api(*args, **kwargs)
reformat_project_relative_path_filter_for_vitest!(args, "api/")
run(*%w[test_api npm run test], *args, **kwargs)
end
def test_web(*args, **kwargs)
reformat_project_relative_path_filter_for_vitest!(args, "web/")
run(*%w[test_web npm run test], *args, **kwargs)
end
def sqlcmd(*args, **kwargs)
db_host = ENV.fetch('DB_HOST', 'localhost')
db_user = ENV.fetch('DB_USER', 'sa')
db_pass = ENV.fetch('DB_PASS', '1m5ecure!')
db_name = ENV.fetch('DB_NAME', 'YHSI')
compose(
*%w[exec db /opt/mssql-tools/bin/sqlcmd],
*%W[-U #{db_user}],
*%W[-P #{db_pass}],
*%W[-H #{db_host}],
*%W[-d #{db_name}],
'-I', # enable quoted identifiers, e.g. "table"."column"
*args,
**kwargs
)
end
def db(*args, **kwargs)
compose(*%w[exec db], *args, **kwargs)
end
def debug
api_container_id = container_id("api")
puts "Waiting for breakpoint to trigger..."
puts "'ctrl-c' to exit."
command = "docker attach --detach-keys ctrl-c #{api_container_id}"
puts "Running: #{command}"
exec(command)
exit 0
end
def npm(*args, **kwargs)
run(*%w[api npm], *args, **kwargs)
end
def ts_node(*args, **kwargs)
run(*%w[api npm run ts-node], *args, **kwargs)
end
def knex(*args, **kwargs)
if RUBY_PLATFORM =~ /linux/
run(*%w[api npm run knex], *args, execution_mode: WAIT_FOR_PROCESS, **kwargs)
file_or_directory = "#{project_root}/api/src/db/migrations"
exit(0) unless take_over_needed?(file_or_directory)
ownit file_or_directory
else
run(*%w[api npm run knex], *args, **kwargs)
end
end
def migrate(*args, **kwargs)
action = args[0]
knex("migrate:#{action}", *args.drop(1), **kwargs)
end
def seed(*args, **kwargs)
action = args[0]
knex("seed:#{action}", *args.drop(1), **kwargs)
end
def ownit(*args, **kwargs)
file_or_directory = args[0]
raise ScriptError, "Must provide a file or directory path." if file_or_directory.nil?
if RUBY_PLATFORM =~ /linux/
puts "Take ownership of the file or directory? #{file_or_directory}"
exec("sudo chown -R #{user_id}:#{group_id} #{file_or_directory}")
else
raise NotImplementedError, "Not implement for platform #{RUBY_PLATFORM}"
end
end
def plantuml_to_png(*args, **kwargs)
file_path = args.pop
raise ScriptError, "Must provide a file path." if file_path.nil?
png_path = file_path.gsub(/\.(wsd|pu|puml|plantuml|uml)$/, ".png")
command = <<~BASH
curl #{args.join(" ")} \
--data-binary @'#{file_path}' \
http://localhost:9999/png > '#{png_path}'
BASH
puts "Running: #{command}"
exec(command)
end
def bash_completions
completions =
public_methods(false)
.reject { |word| %i[call].include?(word) }
.map { |word| METHOD_TO_COMMAND.fetch(word, word) }
puts completions
end
private
def wait_for_process_with_logging(command)
IO.popen("#{command} 2>&1") do |io|
until io.eof?
line = io.gets
puts line
end
end
end
def container_id(container_name, *args, **kwargs)
command = compose_command(*%w[ps -q], container_name, *args, **kwargs)
puts "Running: #{command}"
id_of_container = `#{command}`.chomp
puts "Container id is: #{id_of_container}"
id_of_container
end
def service_running?(container_name)
ps(*%w[-q --status=running], execution_mode: WAIT_FOR_PROCESS, slient: true) != ""
end
def compose_command(*args, **kwargs)
environment = kwargs.fetch(:environment, "development")
"cd #{project_root} && docker compose -f docker-compose.#{environment}.yml #{args.join(" ")}"
end
def project_root
@project_root ||= File.absolute_path("#{__dir__}/..")
end
def take_over_needed?(file_or_directory)
files_owned_by_others =
system("find #{file_or_directory} -not -user #{user_id} -print -quit | grep -q .")
files_owned_by_others
end
def user_id
unless RUBY_PLATFORM =~ /linux/
raise NotImplementedError, "Not implement for platform #{RUBY_PLATFORM}"
end
`id -u`.strip
end
def group_id
unless RUBY_PLATFORM =~ /linux/
raise NotImplementedError, "Not implement for platform #{RUBY_PLATFORM}"
end
`id -g`.strip
end
def reformat_project_relative_path_filter_for_vitest!(args, prefix)
if args.length.positive? && args[0].start_with?(prefix)
src_path_prefix = "#{prefix}src/"
test_path_regex = Regexp.escape(prefix)
src_path_regex = Regexp.escape(src_path_prefix)
if args[0].start_with?(src_path_prefix)
# TODO: handle other file types
args[0] = args[0].gsub(/^#{src_path_regex}/, "tests/").gsub(/\.ts$/, ".test.ts")
else
args[0] = args[0].gsub(/^#{test_path_regex}/, "")
end
puts "Reformatted path filter from project relative to service relative for vitest."
end
end
end
# Only execute main function when file is executed
DevHelper.call(*ARGV) if $PROGRAM_NAME == __FILE__
## Dev completions
# https://iridakos.com/programming/2018/03/01/bash-programmable-completion-tutorial
# _dev_completions () {
# local dev_command_path="$(which dev)"
# local dev_function_names
# dev_function_names="$(ruby "$dev_command_path" bash_completions)"
# # COMP_WORDS: an array of all the words typed after the name of the program the compspec belongs to
# # COMP_CWORD: an index of the COMP_WORDS array pointing to the word the current cursor is at - in other words, the index of the word the cursor was when the tab key was pressed
# # COMP_LINE: the current command line
# COMPREPLY=($(compgen -W "$dev_function_names" "${COMP_WORDS[$COMP_CWORD]}"))
# }
# complete -F _dev_completions dev
# complete -W "allow" direnv
+120
View File
@@ -0,0 +1,120 @@
x-default-environment: &default-environment
TZ: "UTC"
NODE_ENV: development
DB_HOST: db
DB_USERNAME: &default-db-username alphane
DB_DATABASE: alphane_development
DB_PASSWORD: &default-db-password DevPwd99!
DB_PORT: &default-db-port 5432
DB_TRUST_SERVER_CERTIFICATE: "true"
DB_HEALTH_CHECK_INTERVAL_SECONDS: 5
DB_HEALTH_CHECK_TIMEOUT_SECONDS: 10
DB_HEALTH_CHECK_RETRIES: 3
DB_HEALTH_CHECK_START_PERIOD_SECONDS: 5
FRONTEND_URL: "http://localhost:8080"
VITE_APPLICATION_NAME: "ALPHANE"
VITE_API_BASE_URL: "http://localhost:3000"
VITE_AUTH0_CLIENT_ID: "TRlKzdNBynpo9tU1RSmnF0p8d3IEam4J"
VITE_AUTH0_AUDIENCE: "alphane-api"
VITE_AUTH0_DOMAIN: "https://dev-7mdjzcgwirhocfwm.ca.auth0.com"
RELEASE_TAG: "${RELEASE_TAG:-development}"
GIT_COMMIT_HASH: "${GIT_COMMIT_HASH:-not-set}"
services:
api:
build:
context: ./api
dockerfile: development.Dockerfile
image: wrap-api:latest
env_file:
- ./api/.env.development
environment:
<<: *default-environment
tty: true # allows attaching debugger, equivalent of docker exec -t
# stdin_open: true # equivalent of docker exec -i
ports:
- "3000:3000"
- "9229:9229"
volumes:
- ./api:/usr/src/api
- ./.gitignore:/usr/src/.gitignore
- ./.prettierrc.yaml:/usr/src/.prettierrc.yaml
depends_on:
- db
web:
build:
context: ./web
dockerfile: development.Dockerfile
environment:
<<: *default-environment
ports:
- "8080:8080"
volumes:
- ./web:/usr/src/web
- ./.gitignore:/usr/src/.gitignore
- ./.prettierrc.yaml:/usr/src/.prettierrc.yaml
depends_on:
- api
test_api:
build:
context: ./api
dockerfile: development.Dockerfile
command: /bin/true
env_file:
- ./api/.env.development
environment:
<<: *default-environment
NODE_ENV: test
DB_DATABASE: alphane_test
DEFAULT_LOG_LEVEL: "info"
DB_HEALTH_CHECK_START_PERIOD_SECONDS: 0
tty: true
volumes:
- ./api:/usr/src/api
depends_on:
- db
profiles:
- test
test_web:
build:
context: ./web
dockerfile: development.Dockerfile
command: /bin/true
environment:
<<: *default-environment
NODE_ENV: test
tty: true
volumes:
- ./web:/usr/src/web
profiles:
- test
db:
image: postgres:17.6
user: root
environment:
<<: *default-environment
POSTGRES_USER: *default-db-username
POSTGRES_PASSWORD: *default-db-password
ports:
- "5432:5432"
volumes:
- pg-data:/var/lib/postgresql/data
# For easily generating large PlantUML diagrams
# Not relevant to production environment.
# Accessible at http://localhost:9999
plantuml:
image: plantuml/plantuml-server:jetty
ports:
- 9999:8080
environment:
PLANTUML_LIMIT_SIZE: 8192
profiles:
- design
volumes:
pg-data:
+32
View File
@@ -0,0 +1,32 @@
services:
app:
build: .
restart: unless-stopped
env_file:
- .env
environment:
NODE_ENV: production
ports:
- "${HOST_PORT:-3000}:${HOST_PORT:-3000}"
volumes:
- ./.env:/home/node/app/.env.production
depends_on:
- db
db:
image: postgres:17.6
restart: always
env_file:
- .env
environment:
TZ: "UTC"
POSTGRES_USER: "${DB_USER}"
POSTGRES_PASSWORD: "${DB_PASS}"
POSTGRES_DB: "${DB_NAME}"
ports:
- "5432:5432"
volumes:
- pg-data:/var/lib/postgresql/data
volumes:
db_data:
+1414
View File
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
{
"name": "alphane-development-tooling",
"private": true,
"devDependencies": {
"eslint": "^9.33.0",
"eslint-config-prettier": "^10.1.8",
"prettier": "^3.6.2",
"prettier-plugin-embed": "^0.5.1",
"prettier-plugin-sql": "^0.19.2"
}
}