Git Product home page Git Product logo

tillkuhn / angkor Goto Github PK

View Code? Open in Web Editor NEW
15.0 5.0 4.0 15.83 MB

๐ŸŒ…(Mostly) educational app to manage favorite locations and recipes. Techstack Frontend: Angular 16 (TypeScript, Mapbox GL), Backend: Spring Boot 3.2 (JDK 21, Kotlin, PostgreSQL, Kafka, Cognito), Go Microservices, Docker, Terraform managed AWS Infrastructure

License: Apache License 2.0

Dockerfile 0.41% Kotlin 31.50% HCL 8.31% Makefile 4.77% Shell 3.11% JavaScript 0.22% TypeScript 29.21% HTML 7.20% Go 12.24% SCSS 2.75% PLpgSQL 0.20% CSS 0.09%
spring-boot kotlin terraform aws angular letsencrypt postgresql restful mapbox-gl golang cognito typescript antora docker-compose kafka

angkor's Introduction

Angular Kotlin Spring Go Terraform AWS Postgres Docker

Releases GitHub language count License Quality Gate Status kotlin-ci angular-ci Go Report Card

Dynamic JSON Badge Dynamic TOML Badge Dynamic TOML Badge

Project "Angkor" - Angular Golang Kotlin RESTful Webapp Stack

This (almost) purely educational app manages places I'd like to visit some day, and helps me to keep track of more or less exotic dishe recipes.

Key technologies: Angular based single-page app with Mapbox GL, AWS Cognito for OAuth2, PostgreSQL DB and S3 for persistence and a Spring Boot backend written in Kotlin, various spin-off tools written in Golang, all provisioned to AWS Infrastructure with Terraform and lots of Confidence.

tl;dr

$ make angkor
๐ŸŒ‡ Successfully Built Angkor 

Modules

Angkor is a monorepo which combines the following modules and technologies:

Path Descriptions Technologies / Tools / Language(s) Build Status
/terraform Cloud Infrastructure as Code Terraform AWS Linux  terraform-ci
/kotlin Server Backend Kotlin Spring, Gradle Postgres Docker  kotlin-ci
/angular Frontend and reverse proxy Angular TypeScript Yarn Nginx Docker  angular-ci
/go Supporting services written in Go Go JWT Docker  golang-ci
/docs Project Documentation Antora, AsciiDoc  antora-ci

Components & Infrastructure

You should have AWS CLI and most importantly Terraform installed. In a nutshell the application's neighborhood looks as follows:

Impressions

Places to Go (Details)

WorldWideMap (Overview)

Wish a Dish (Search)

Angkor wasn't built in a day ...

This project uses the good old GNU Make utility to manage all tasks for terraform, gradle, yarn and whatever else we have in our ecosystem. Run make without args to see what's possible, open the Makefile to look beyond!

$ make

  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
 โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ• โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•
 โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—
 โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘ โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘
 โ•šโ•โ•  โ•šโ•โ•โ•šโ•โ•  โ•šโ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•  โ•šโ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•  โ•šโ•โ•

Available Commands:
  api-clean            Cleans up ./kotlin/build folder
  api-build            Assembles backend jar in ./api/build with gradle (alias: assemble)
  api-test             Runs spring boot unit and integration tests in ./kotlin
  api-run              Runs springBoot API in ./kotlin using gradle bootRun (alias: bootrun)
  api-mock             Runs OIDC (and potentially other) mock service for api

  ui-build             Run ng build  in ./ui
  ui-build-prod        Run ng build --prod in ./ui
  ui-test              Runs chromeHeadless tests in ./angular
  ui-run               Run angular with ng serve and opens WebUI in browser (alias: serve,open,angular)
  ui-mocks             Run json-server on foreground to mock API services for UI (alias: mock)

  tf-init              Runs terraform init on working directory ./terraform, switch to
  tf-plan              Runs terraform plan with implicit init and fmt (alias: plan)
  tf-apply             Runs terraform apply with auto-approval (alias: apply)


  docs-clean           Cleanup docs build directory
  docs-build           Generate documentation site using antora-playbook.yml
  docs-push            Generate documentation site and push to s3
  docs-deploy          Deploys docs with subsequent pull and restart of server on EC2 (alias: docs)


  all-clean            Clean up build artifact directories in backend and frontend (alias: clean)
  all-build            Builds frontend and backend (alias: build)
  all-test             Builds frontend and backend (alias: build)
  all-deploy           builds and deploys frontend and backend images (alias deploy)

  angular-clean        Remove angular dist folder ./angular/dist
  angkor               The ultimate target - builds and deploys everything ๐Ÿฆ„

  release              create final release tag with semtag

  git-clean            git cleanup, e.g. delete up stale git branches

I want more Documentation

Seriously? Check our Dedicated angkor-docs project built with Antora

Contribute

See CONTRIBUTING.md

angkor's People

Contributors

dependabot[bot] avatar tillkuhn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

angkor's Issues

Make browser cache identical image with different aws s3 presigned url?

Feature
Currently imagine sends a 307 to the actual presigned URL, which is regenerated every time (i.e. also on browser refresh) even when the URL is still valid, i.e. not expired. This creates lots of HTTP request especially ob overview pages that uses presigned image URL for avatar items

URL References

Upgrade to Spring 3.0 / Hibernate 6 / Jakarta EE 9

Map Clusters per country (number of dishes), support country deeplinks

Feature
Map should show centers of countries so dishes can deeplink into a MapLocation based on its (iso-)code

URL References

// add markers to map
geojson.features.forEach(function (marker) {
// create a DOM element for the marker
var el = document.createElement('div');
el.className = 'marker';
el.style.backgroundImage =
'url(https://placekitten.com/g/' +
marker.properties.iconSize.join('/') +
'/)';
el.style.width = marker.properties.iconSize[0] + 'px';
el.style.height = marker.properties.iconSize[1] + 'px';
el.style.backgroundSize = '100%';

Move Master -> Main

Feature
It's about time

URL References

Last todo:

git push origin --delete master

Setup OAuth2 Authentication

Is your feature request related to a problem? Please describe.
we need to habe protected areas in the webapp that enforce authentication

Describe the solution you'd like
we'd like to integrate with AWS Cognito and support social identities

Describe alternatives you've considered
using basic auth in nginx as a starter

Additional context
check out sso-spring-security-oauth2

fix issues with coordinates save JSONObject["address"] not found

Describe the bug
-15.2646156,-145.1163131.
error 500

Additional context
Add any other context about the problem here.

023-02-01 20:17:49Z DEBUG n.t.angkor.service.PlaceService : AreaCode pf or GeoAddress null empty, lookup geoPoint for [-145.1163131, -15.2646156]
2023-02-01 20:17:49Z  INFO n.t.angkor.service.GeoService   : Downloading geo info for Coordinates(lon=-145.1163131, lat=-15.2646156) from https://nominatim.openstreetmap.org status=200
2023-02-01 20:17:49Z  INFO n.t.angkor.service.GeoService   : Json: {"error":"Unable to geocode"}
2023-02-01 20:17:49Z ERROR .c.c.C.[.[.[.[dispatcherServlet]: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.json.JSONException: JSONObject["address"] not found.] with root cause

org.json.JSONException: JSONObject["address"] not found.
	at org.json.JSONObject.get(JSONObject.java:471) ~[json-20160212.jar!/:na]
	at org.json.JSONObject.getJSONObject(JSONObject.java:636) ~[json-20160212.jar!/:na]
	at net.timafe.angkor.service.GeoService.mapToOSMPlaceSummary(GeoService.kt:101) ~[classes!/:na]
	at net.timafe.angkor.service.GeoService.reverseLookup(GeoService.kt:94) ~[classes!/:na]
	at net.timafe.angkor.service.GeoService.reverseLookupWithRateLimit(GeoService.kt:60) ~[classes!/:na]
	at net.timafe.angkor.service.AbstractLocationService.save(AbstractLocationService.kt:24) ~[classes!/:na]
	at net.timafe.angkor.service.PlaceService.save(PlaceService.kt:40) ~[classes!/:na]

Imagine: If URL has no extension such as .jpg, thumbnail creation fails

check Laab, should derive extension from mimetype if not present in filename / URL

2020/12/20 22:30:11 Convert /tmp/Laab-Tofu temporary thumbnail /tmp/Laab-Tofu_150 qual 80
2020/12/20 22:30:11 ERROR failed to create resize image /tmp/Laab-Tofu_150: imaging: unsupported image format, skipping

Also suffixes after the url cause issues e.g.
https://www.bla.com/kritharaki-tomaten-sauce.jpg?v=1-0, maybe RawQuery in pkg/net/url/ helps

a%2F960x960%2F00%kritharaki-in-tomaten-sauce.jpg%3Fv%3D1-0&Size=102485
2020/12/21 18:57:50 ERROR: cannot upload  imagine/dishes/9d46fc74-ac3d-48f2-a352-60400fde35de/kritharaki-in-tomaten-sauce.jpg?v=1-0: InvalidTag: The TagValue you have provided is invalid

WiP: Komoot Tour Import Integration

Feature
Places / links which point to Kommoot tours could support a preview of the tour and/or auto-download a preview of the tour as image.

<a href="https://www.komoot.de/tour/281323266?ref=wtd" target="_blank" rel="nofollow noopener noreferrer">
<img src="https://www.komoot.de/tour/281323266/embed?image=1&hm=true&profile=1&width=640&height=680" width="640" height="680"/>
</a>

URL References

Sample Flow

antora webhook action fails

Describe the bug

Run distributhor/workflow-webhook@v3
(....)
"/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" -v "/home/runner/work/angkor/angkor":"/github/workspace" ghcr.io/distributhor/workflow-webhook-container:v3.0.2
Error: Unable to process file command 'output' successfully.
Error: Invalid format '  "result" : true'

delete dish raises console error and does nothing

main-es2015.6e9846e72733d8727800.js:1 ERROR TypeError: e.confirmDeleteDialog is not a function
    at main-es2015.6e9846e72733d8727800.js:1
    at Us (main-es2015.6e9846e72733d8727800.js:1)
    at r (main-es2015.6e9846e72733d8727800.js:1)
    at HTMLAnchorElement.<anonymous> (main-es2015.6e9846e72733d8727800.js:1)
    at l.invokeTask (polyfills-es2015.693367d8d653ac7f471f.js:1)

Setup SES Mailing Notifications for due notes

replace deprecated moment.js with date-fns or similar

Allow users to request data deletion in accordance with FB Policy requirements

Customize Dependabot, especially for npm and gradle

Feature
https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#ignore

Example

# Use `ignore` to specify dependencies that should not be updated

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    ignore:
      - dependency-name: "express"
        # For Express, ignore all updates for version 4 and 5
        versions: ["4.x", "5.x"]
        # For Lodash, ignore all updates
      - dependency-name: "lodash"
        # For AWS SDK, ignore all patch updates
      - dependency-name: "aws-sdk"
        update-types: ["version-update:semver-patch"]

Scheldule certbot renew job

setup nightly or weekly job as described in renewing-certificates

make use of hooks to temporarily "free" port 80 from nginx (we used standalone mode for obtaining) e.g.

certbot renew --pre-hook "docker-compose stop angkor-ui" --post-hook "docker-compose start angkor-ui"

Verify Dockerfile in github actions with hadolint prior to Docker Push

github.com/hadolint/hadolint
Maybe use existing marketplace action, or do it yourself e.g.

$curl -sS -L https://github.com/hadolint/hadolint/releases/download/v1.19.0/hadolint-Linux-x86_64 \
--output /tmp/hadolint && chmod u+x /tmp/hadolint

$ /tmp/hadolint Dockerfile && echo "Dockerfile OK"
Dockerfile:27 DL3025 Use arguments JSON notation for CMD and ENTRYPOINT arguments

Sample output:

Dockerfile:27 DL3025 Use arguments JSON notation for CMD and ENTRYPOINT arguments

Get Time Zone Handling ISO8601 vs Postgres vs Javascript

2015
https://stackoverflow.com/a/15952652/4292075

JSON itself does not specify how dates should be represented, but JavaScript does.

You should use the format emitted by Date's toJSON method:

2012-04-23T18:25:43.511Z

Here's why:

It's human readable but also succinct
It sorts correctly
It includes fractional seconds, which can help re-establish chronology
It conforms to ISO 8601
ISO 8601 has been well-established internationally for more than a decade
ISO 8601 is endorsed by W3C, RFC3339, and XKCD

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.