Skip to content

feat: add tsoa for API type control and documentation#1501

Open
Andreybest wants to merge 4 commits intofinos:mainfrom
Andreybest:1430-api-checking-docs
Open

feat: add tsoa for API type control and documentation#1501
Andreybest wants to merge 4 commits intofinos:mainfrom
Andreybest:1430-api-checking-docs

Conversation

@Andreybest
Copy link
Copy Markdown

Resolves #1430.

Add tsoa for endpoint type checking and generation of OpenAPI documentation. Generates swagger.json to /dist folder.
All tests for endpoints that were present, passes (with minor changes), all logic is preserved.

Caveats:

  1. tsoa checks for field presence, but does not check if string in field is empty, thus should be checked manually (or I've missed something in configuration). For example: POST api/v1/push/{id}/reject (rejectPush), if empty or whitespaces provided, will not check for it, thus old logic for theck with .trim() is left.
  2. tsoa has a configuration field noImplicitAdditionalProperties, that allows to change behavior of endpoints for rejecting of excess fields. Currently set to ignore due to POST api/v1/repo (createRepo), this endpoint passes body to a db.createRepo(body), and inner type expects additionalProperties that are passed to a row in a DB. Question: is this expected or not? If not, maybe we should enable more strict mode on noImplicitAdditionalProperties? :)

@Andreybest Andreybest requested a review from a team as a code owner April 10, 2026 12:54
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 10, 2026

Deploy Preview for endearing-brigadeiros-63f9d0 canceled.

Name Link
🔨 Latest commit 9520a31
🔍 Latest deploy log https://app.netlify.com/projects/endearing-brigadeiros-63f9d0/deploys/69e81cb7c615fb0008b12e37

@Andreybest Andreybest requested a review from jescalada April 10, 2026 12:54
Copy link
Copy Markdown
Contributor

@jescalada jescalada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution, @Andreybest! 🚀

Things are looking good so far, just a few things to mention other than the code comments:

  • It'd be great to have screenshots of the generated OpenAPI spec to see if things are working as we hoped
  • I noticed a duplicate interface (AttestationAnswer) and am wondering if there aren't other interfaces that can be reused or combined into one
  • Test coverage seems to go down somewhat (-1.5%), we should improve coverage on any code additions such as proxyStore.ts, etc.

We might need another review since the changes are quite large @finos/git-proxy-maintainers

Comment thread package.json
"start": "concurrently \"npm run server\" \"npm run client\"",
"build": "npm run generate-config-types && npm run build-ui && npm run build-ts",
"build-ts": "tsc --project tsconfig.publish.json && node scripts/fix-shebang.js",
"build-ts": "npm run build-tsoa && tsc --project tsconfig.publish.json && node scripts/fix-shebang.js",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonder if this can be simplified or done elsewhere? I feel the build-ts script is starting to get too cluttered. Perhaps we could rename the build-tsoa script from below to something more descriptive like build-api-spec, and then call build-api-spec && build-ts when needed?

Feel free to suggest alternatives 🙂

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build-tsoa builds swagger.json and generatedRoutes.ts which is required for index.ts, without it - build fails, so its is essential part of a build (unfortunately). Considering this thing, build-tsoa naming makes more sense than build-api-spec because we build spec and routes (tsoa spec-and-routes).

Comment thread src/app.ts
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems Git mistakenly interpreted this as a rename... Don't think much can be done here since the diff looks valid 👍🏼

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, this is a rewrite of /src/service/passport/jwtAuthHandler.ts? Is this necessary, and if so, should we delete that version instead?

We should double check that all usages of jwtAuthHandler still work as intended.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunatelly - yes. TSOA expect an expressAuthentication with a different set of rules. Deleted /src/service/passport/jwtAuthHandler.ts. Yes, it is the rewrite.
Checked and fixed tests for jwtAuth


// ---------- Response types ----------

interface AuthResources {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible, these types should be stored in a separate file and imported here (and in other controllers) if necessary

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to /interfaces/{controller_name}.interfaces.ts, please let me know if that is alright :)

}

// TODO: provide separate auth endpoints for each auth strategy or chain compatibile auth strategies
// TODO: if providing separate auth methods, inform the frontend so it has relevant UI elements and appropriate client-side behavior
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware these comments were here before, but I believe the /auth/config endpoint is being used in the UI right now to fetch the auth methods. I think we can safely delete the "seperate auth methods" one.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted!


if (currentHosts.length < previousHosts.length) {
console.log('Restarting the proxy to remove a host');
const proxy = getProxy();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another bit to double-check for proper restart behaviour

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the request/response interfaces could be stored here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to common.interfaces.ts. To follow naming with other responses/requests

* When `username` is supplied the request is pre-authenticated via middleware,
* simulating a session-authenticated user.
*/
const newApp = (username?: string, isAdmin = false): Express => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the comment on users.test.ts, I don't think setting isAuthenticated is necessary as it's exclusively used for the jwtAuthHandler which is disabled by default.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Comment thread test/services/routes/users.test.ts Outdated
app = express();
app.use(express.json());
app.use('/users', usersRouter);
// Pre-authenticate so JWT security allows through in tests.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is a bit misleading - JWT auth isn't required by default. The isAuthenticated flag is used only for JWT anyways and shouldn't be necessary here AFAIK 🤔

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Comment thread tsoa.json
"spec": {
"outputDirectory": "dist",
"specVersion": 3,
"securityDefinitions": {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth mentioning that JWT API auth is optional - and might be subject to change as it's a feature only used by our org. It's a bit confusing and poorly documented so we'll be polishing things once v2 is out...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, it is only used for 2 things:

  1. For a name in the decorator to be used as Security('jwt')
  2. As a documentation for OpenAPI

It does not do any functionally, but it is required anyway if we want to use Security decorator properly

@kriswest
Copy link
Copy Markdown
Contributor

@jescalada and @Andreybest There is a docusaurus plugin for rendering OpenAPI docs at:

https://docusaurus-openapi.tryingpan.dev/
https://github.com/PaloAltoNetworks/docusaurus-openapi-docs

Whereas in the FDC3 website we use a very simple static page and the Redoc lib to render the same: https://github.com/finos/FDC3/blob/main/website/src/pages/schemas/next/app-directory.html

Note that you have to link to this as an external link or docusaurus will return a 404 when navigating within the site:

https://github.com/finos/FDC3/blob/ffea3be0735bdd7a72ffba5473addfe49535833e/website/docs/app-directory/spec.md?plain=1#L7-L13

@Andreybest
Copy link
Copy Markdown
Author

Thank you for the review @jescalada !
Can you please review it again? Applied changes to most of your comments :)

  1. Screenshot of swagger
image 2. Duplicate removed, quickly checked, should be no more repetiotions (but not sure) 3. Don't see a message from code cov bot on this matter, can you please show me where I can find a code coverage stats?

@Andreybest
Copy link
Copy Markdown
Author

Checked all commits on main branch for new changes to logic for endpoints. None was changed, checked up to commit 6981427c50a5e5ccd3e91a2d4229b27135f8dcc3

@Andreybest Andreybest requested a review from jescalada April 22, 2026 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve API types and documentation

3 participants