Development Guide

This guide covers the development workflow, coding standards, and contribution guidelines for the Wallet Service.

Prerequisites


Getting Started

1. Clone and Install

git clone <repository-url>
cd wallet-service
npm install

2. Configure Environment

cp example.env .env
# Edit .env with your development credentials

3. Start Development Server

npm run dev

The server starts at http://localhost:3000 with hot-reload enabled.


Available Scripts

Command Description
npm run dev Start development server with hot-reload
npm run build Build for production
npm run start Start production server
npm run test Run tests
npm run lint Run linter
npm run lint:fix Fix linting issues

Project Structure

src/
├── index.ts              # Entry point
├── server.ts             # Server bootstrap
├── app/
│   ├── app.ts            # Fastify application
│   ├── app.environment.ts # Environment config
│   ├── views/            # Template files
│   └── public/           # Static assets
└── lib/
    ├── controllers/      # Route handlers
    ├── services/         # Business logic
    ├── modules/          # Utility modules
    ├── jobs/             # Background tasks
    ├── util/             # Helper functions
    ├── assets/           # Static resources
    └── certs/            # Certificates

Coding Standards

TypeScript Guidelines

// ✓ Good
async function getPass(serialNumber: string): Promise<Buffer> {
  // ...
}

// ✗ Avoid
async function getPass(serialNumber): any {
  // ...
}

Code Style

The project uses XO for linting with custom rules:

Run the linter before committing:

npm run lint

Git Workflow

Commit Messages

This project follows Conventional Commits:

<type>[optional scope]: <description>

[optional body]

[optional footer]

Types:

Type Description
feat New feature
fix Bug fix
docs Documentation only
style Code style (formatting, etc.)
refactor Code refactoring
perf Performance improvement
test Adding tests
chore Maintenance tasks

Examples:

# Feature
git commit -m "feat(apple): add push notification support"

# Bug fix
git commit -m "fix(auth): correct token validation regex"

# Breaking change
git commit -m "feat(api)!: change response format

BREAKING CHANGE: response now uses 'data' wrapper"

Branch Strategy


Adding New Features

1. Create a Controller

Controllers handle HTTP requests:

// src/lib/controllers/example.controller.ts
import { Controller, GET, POST } from 'fastify-decorators';
import type { FastifyRequest, FastifyReply } from 'fastify';

@Controller('/example')
export default class ExampleController {
  @GET('/')
  async list(request: FastifyRequest, reply: FastifyReply) {
    return { items: [] };
  }

  @POST('/')
  async create(request: FastifyRequest, reply: FastifyReply) {
    // Handle creation
  }
}

2. Create a Service

Services contain business logic:

// src/lib/services/example.service.ts
import { Service, Initializer } from '@fastify-decorators/simple-di';

@Service()
export class ExampleService {
  @Initializer()
  async init() {
    // Initialize service
  }

  async doSomething(): Promise<void> {
    // Business logic
  }
}

3. Add Request Validation

Define schemas for request validation:

// src/lib/controllers/example.schema.ts
export const createSchema = {
  body: {
    type: 'object',
    required: ['name'],
    properties: {
      name: { type: 'string' },
      description: { type: 'string' }
    }
  },
  response: {
    200: {
      type: 'object',
      properties: {
        id: { type: 'string' },
        name: { type: 'string' }
      }
    }
  }
};

Working with External Services

Salesforce

Member data is fetched from Salesforce via the salesforce.ts module:

import { getMemberData } from '../modules/salesforce';

const memberData = await getMemberData(salesforceId);

Apple Wallet

Generate passes using the apple.ts module:

import { createApplePass } from '../modules/apple';

const passBuffer = await createApplePass(memberData);

Google Wallet

Generate save links using the google.ts module:

import { GoogleGeneric } from '../modules/google';

const saveUrl = await GoogleGeneric.createPass(memberData);

Debugging

Enable Debug Logging

Set environment variables:

LOGGER=true
LOG_LEVEL=debug

VS Code Launch Configuration

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Debug Server",
      "program": "${workspaceFolder}/src/index.ts",
      "preLaunchTask": "npm: build",
      "outFiles": ["${workspaceFolder}/build/**/*.js"]
    }
  ]
}

Testing Endpoints

Use the Swagger UI at /docs or tools like:


Common Issues

Certificate Errors

Ensure certificates are correctly placed in src/lib/certs/ and the passphrase is set in .env.

Salesforce Connection

Verify Salesforce credentials and check if your IP is whitelisted.

Port Already in Use

Change the PORT in .env or stop the conflicting process:

lsof -i :3000
kill -9 <PID>

Resources