diff --git a/.dockerignore b/.dockerignore index 26feb7a..9797baf 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,6 @@ /.dockerignore /.gitignore +/docker-compose.yaml /justfile /Dockerfile /README.md diff --git a/bin/app.ts b/bin/app.ts index dd47d27..1f95820 100644 --- a/bin/app.ts +++ b/bin/app.ts @@ -31,29 +31,32 @@ app.use( express.json(), expressMiddleware(server, { async context({ req }) { - const user = await (async () => { - console.log("Authorization:", req.headers.authorization); - const auth = req.headers.authorization; - if (!auth) return; - const [user] = await sql<[{ id: string; language: number }?]>` + try { + const user = await (async () => { + if (!req.headers.authorization) return; + const [user] = await sql<[{ id: string; language: number }?]>` SELECT workeruuid AS id, workerlanguageid AS language FROM public.worker - WHERE workerexternalid = ${auth}; + WHERE workerexternalid = ${req.headers.authorization}; `; - return user; - })(); + return user; + })(); - const ctx = { - authScope: user?.id, - languageTypeId: user?.language ?? 20, - }; + const ctx = { + authScope: user?.id, + languageTypeId: user?.language ?? 20, + }; - return { - ...ctx, - orm: orm(ctx), - }; + return { + ...ctx, + orm: orm(ctx), + }; + } catch (e) { + console.error(e); + throw e; + } }, }), ); diff --git a/copilot/.workspace b/copilot/.workspace index 4b07ef2..683fbe7 100644 --- a/copilot/.workspace +++ b/copilot/.workspace @@ -1 +1 @@ -application: tendrel-graphql +application: graphql diff --git a/copilot/graphql/manifest.yml b/copilot/graphql/manifest.yml index 3313171..afde049 100644 --- a/copilot/graphql/manifest.yml +++ b/copilot/graphql/manifest.yml @@ -1,11 +1,10 @@ # The manifest for the "graphql" service. -# Read the full specification for the "Request-Driven Web Service" type at: -# https://aws.github.io/copilot-cli/docs/manifest/rd-web-service/ +# Read the full specification for the "Load Balanced Web Service" type at: +# https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/ -# Your service name will be used in naming your resources like log groups, App Runner services, etc. +# Your service name will be used in naming your resources like log groups, ECS services, etc. name: graphql -# The "architecture" of the service you're running. -type: Request-Driven Web Service +type: Load Balanced Web Service image: # Docker build arguments. @@ -14,8 +13,14 @@ image: # Port exposed through your container to route traffic to it. port: 4000 -http: - path: /v1 # gql.tendrel.io/v1 +http: false +nlb: + port: 443/tls + target_port: 4000 + +network: + vpc: + placement: private # Number of CPU units for the task. cpu: 1024 @@ -40,6 +45,8 @@ environments: LOG_LEVEL: debug NODE_ENV: development test: + nlb: + alias: test.graphql.tendrel.io secrets: DB_USERNAME: secretsmanager: "/database/service/graphql:username::" diff --git a/docker-compose.yaml b/docker-compose.yaml index 5094d1f..929bc50 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -4,7 +4,7 @@ services: environment: POSTGRES_PASSWORD: password ports: - - 5432:5432 + - 5433:5432 volumes: - pgdata:/var/lib/postgresql/data diff --git a/flake.nix b/flake.nix index 030ee59..9c5bf77 100644 --- a/flake.nix +++ b/flake.nix @@ -37,6 +37,7 @@ biome bun just + postgresql (stdenv.mkDerivation rec { pname = "copilot-cli"; version = "1.33.3"; diff --git a/lib/schema/resolvers/Customer.ts b/lib/schema/resolvers/Customer.ts index 364ef7c..6d6a072 100644 --- a/lib/schema/resolvers/Customer.ts +++ b/lib/schema/resolvers/Customer.ts @@ -1,9 +1,5 @@ import { sql } from "@/datasources/postgres"; -import type { - CustomerResolvers, - Language, - Name, -} from "./../__generated__/types.generated"; +import type { CustomerResolvers, Language, Name } from "@/schema"; export const Customer: CustomerResolvers = { async name(parent, _, ctx) { const [name] = await sql<[Name]>` diff --git a/lib/schema/resolvers/Language.ts b/lib/schema/resolvers/Language.ts index 963fd4b..63c5166 100644 --- a/lib/schema/resolvers/Language.ts +++ b/lib/schema/resolvers/Language.ts @@ -1,8 +1,6 @@ import { sql } from "@/datasources/postgres"; -import type { - LanguageResolvers, - Name, -} from "./../__generated__/types.generated"; +import type { LanguageResolvers, Name } from "@/schema"; + export const Language: LanguageResolvers = { async name(parent, _, ctx) { const [name] = await sql<[Name?]>` @@ -29,6 +27,7 @@ export const Language: LanguageResolvers = { ON m.languagemastersourcelanguagetypeid = s.systagid WHERE m.languagemasterid = ${parent.name_id}; `; + return fallback; } diff --git a/lib/schema/resolvers/Location.ts b/lib/schema/resolvers/Location.ts index 0d420e4..85bf9ae 100644 --- a/lib/schema/resolvers/Location.ts +++ b/lib/schema/resolvers/Location.ts @@ -1,4 +1,20 @@ -import type { LocationResolvers } from "./../__generated__/types.generated"; +import { sql } from "@/datasources/postgres"; +import type { LocationResolvers, Name } from "@/schema"; export const Location: LocationResolvers = { - /* Implement Location resolver logic here */ + async name(parent, _, ctx) { + const [name] = await sql<[Name]>` + SELECT + COALESCE(t.languagetranslationid, m.languagemasterid) AS id, + COALESCE(t.languagetranslationtypeid, m.languagemastersourcelanguagetypeid) AS language_id, + COALESCE(t.languagetranslationvalue, m.languagemastersource) AS value + FROM public.languagemaster AS m + LEFT JOIN public.languagetranslations AS t + ON + m.languagemasterid = t.languagetranslationmasterid + AND t.languagetranslationtypeid = ${ctx.languageTypeId} + WHERE m.languagemasterid = ${parent.name_id}; + `; + + return name; + }, }; diff --git a/lib/schema/resolvers/Name.ts b/lib/schema/resolvers/Name.ts index 3444c5c..114ccb4 100644 --- a/lib/schema/resolvers/Name.ts +++ b/lib/schema/resolvers/Name.ts @@ -1,15 +1,8 @@ import { sql } from "@/datasources/postgres"; -import type { - Language, - NameResolvers, -} from "./../__generated__/types.generated"; +import type { Language, NameResolvers } from "@/schema"; + export const Name: NameResolvers = { async language(parent) { - console.log( - "typeof parent.language_id =:", - typeof parent.language_id, - parent.language_id, - ); const [language] = await sql<[Language]>` SELECT systaguuid AS id, diff --git a/lib/schema/resolvers/Query/customer.ts b/lib/schema/resolvers/Query/customer.ts index a0f8197..00519ca 100644 --- a/lib/schema/resolvers/Query/customer.ts +++ b/lib/schema/resolvers/Query/customer.ts @@ -1,6 +1,6 @@ import type { QueryResolver } from "@/schema/resolvers"; -export const customer: NonNullable = async ( +export const customer: QueryResolver<"customer"> = async ( _, { id }, { orm }, diff --git a/lib/schema/resolvers/Query/customers.ts b/lib/schema/resolvers/Query/customers.ts index ea9c665..5d4ef1d 100644 --- a/lib/schema/resolvers/Query/customers.ts +++ b/lib/schema/resolvers/Query/customers.ts @@ -1,12 +1,9 @@ import { sql } from "@/datasources/postgres"; -import type { Customer, QueryResolvers } from "@/schema"; +import type { Customer } from "@/schema"; +import type { QueryResolver } from "@/schema/resolvers"; import { GraphQLError } from "graphql"; -export const customers: NonNullable = async ( - _, - __, - ctx, -) => { +export const customers: QueryResolver<"customers"> = async (_, __, ctx) => { const { authScope } = ctx; if (!authScope) diff --git a/lib/schema/resolvers/Query/locations.ts b/lib/schema/resolvers/Query/locations.ts index 9ba8e19..8564d5d 100644 --- a/lib/schema/resolvers/Query/locations.ts +++ b/lib/schema/resolvers/Query/locations.ts @@ -1,10 +1,30 @@ -import type { QueryResolvers } from "./../../__generated__/types.generated"; +import { sql } from "@/datasources/postgres"; +import type { Location } from "@/schema"; +import type { QueryResolver } from "@/schema/resolvers"; +import { GraphQLError } from "graphql"; -export const locations: NonNullable = async ( +export const locations: QueryResolver<"locations"> = async ( _, - { customerId, options }, - { languageTypeId }, + { customerId }, + { authScope }, ) => { - return []; -}; + if (!authScope) { + throw new GraphQLError("Unauthenticated", { + extensions: { + code: 401, + }, + }); + } + return await sql` + SELECT + l.locationuuid AS id, + l.locationnameid AS name_id, + l.locationparentid AS parent_id + FROM public.location AS l + INNER JOIN public.customer AS c + ON l.locationcustomerid = c.customerid + WHERE + c.customeruuid = ${customerId}; + `; +}; diff --git a/lib/schema/resolvers/Tag.ts b/lib/schema/resolvers/Tag.ts index 2233e05..7b5dc7f 100644 --- a/lib/schema/resolvers/Tag.ts +++ b/lib/schema/resolvers/Tag.ts @@ -1,4 +1,5 @@ -import type { TagResolvers } from "./../__generated__/types.generated"; +import type { TagResolvers } from "@/schema"; + export const Tag: TagResolvers = { /* Implement Tag resolver logic here */ };