# TypeScript के साथ हेल्थकेयर API कैसे बनाएं

> ट्यूटोरियल: एक्सप्रेस API TypeScript में जो पेशेंट रिकॉर्ड बनाता है, ब्लड-प्रेशर रीडिंग को FHIR R4 ऑब्जर्वेशन के रूप में स्टोर करता है, उन्हें वापस पढ़ता है, एरर को मैप करता है और वेबहुक को वेरिफाई करता है — बिना अपने किसी मेडिकल डेटाबेस के।

Source: https://developers.anpheros.com/hi/guides/healthcare-api-typescript

**यह ट्यूटोरियल एक्सप्रेस के साथ TypeScript में ब्लड-प्रेशर ट्रैकिंग ऐप का बैकएंड API बनाता है: साइन-अप यूजर का मेडिकल रिकॉर्ड बनाता है, रीडिंग को कोडेड HL7 FHIR R4 ऑब्जर्वेशन के रूप में स्टोर किया जाता है, ऐप उन्हें वापस पढ़ता है, और एक वेबहुक एंडपॉइंट नए डेटा के बारे में सुनता है, बिना अपने किसी मेडिकल डेटाबेस के।** आपका API आपके प्रोडक्ट (यूजर, सेशन, सेटिंग्स) के लिए विशिष्ट चीजों को रखता है। मेडिकल डेटा, उसका इतिहास, सहमति और प्रोवेनेंस Anpheros में रहते हैं, जिसे आप [TypeScript SDK](https://developers.anpheros.com/hi/guides/sdks) के माध्यम से कॉल करते हैं।

## आर्किटेक्चर

```
 mobile / web app ──► your API (Express, TypeScript) ──► Anpheros (FHIR R4 record per patient)
                       │  users, sessions, settings        │  observations, conditions, documents,
                       │  user id → patient id              │  provenance, consent, audit
                       ◄──────────── webhooks ──────────────┘
```

आपका डेटाबेस प्रति उपयोगकर्ता एक अतिरिक्त कॉलम संग्रहीत करता है: उनका Anpheros रोगी आईडी। सब कुछ नैदानिक API के माध्यम से जाता है, इसलिए यह कोडित, संस्करणित और किसी भी FHIR सिस्टम या रोगी के अन्य ऐप्स द्वारा पढ़ा जा सकता है, जिसकी वे सहमति देते हैं। [मेडिकल ऐप बैकएंड और डेटाबेस](https://developers.anpheros.com/hi/guides/medical-app-backend) विस्तार से विभाजन की व्याख्या करता है।

## शुरू करने से पहले

- Node.js 18 या नया संस्करण।
- [platform.anpheros.com/dashboard](https://platform.anpheros.com/dashboard/) से एक सैंडबॉक्स कुंजी (`sk_test_…`) (**सैंडबॉक्स कुंजी प्राप्त करें**)। इसे केवल सर्वर पर रखें; यह कभी भी ऐप तक नहीं पहुंचनी चाहिए।

```bash
mkdir bp-api && cd bp-api
npm init -y && npm pkg set type=module
npm install express @anpheros/sdk
npm install -D typescript tsx @types/express @types/node
export ANPHEROS_KEY=sk_test_…
```

## चरण 1: क्लाइंट और आपका उपयोगकर्ता स्टोर

```ts
// server.ts
import express from 'express';
import { Anpheros, AnpherosError, apiKey, verifyWebhookSignature } from '@anpheros/sdk';

const anpheros = new Anpheros({ auth: apiKey(process.env.ANPHEROS_KEY!) });
const app = express();

// Your own user table. In production this is your database; the only medical link is patientId.
type User = { id: string; email: string; patientId: string };
const users = new Map<string, User>();

// Stand-in for your real authentication (session cookie, JWT…): it must set the signed-in user.
function currentUser(req: express.Request): User {
  const user = users.get(req.header('x-user-id') ?? '');
  if (!user) throw new HttpError(401, 'not signed in');
  return user;
}

class HttpError extends Error {
  constructor(readonly status: number, message: string) { super(message); }
}
```

## चरण 2: साइन-अप मेडिकल रिकॉर्ड बनाता है

जब कोई साइन-अप करता है, तो Anpheros में उनका मरीज़ बनाएं और `identifiers` में अपना उपयोगकर्ता आईडी डालें, ताकि रिकॉर्ड को हमेशा आपकी तरफ से ढूंढा जा सके:

```ts
app.post('/signup', express.json(), async (req, res, next) => {
  try {
    const { email, given, family, birthDate } = req.body;
    const userId = crypto.randomUUID();
    const patient = await anpheros.patients.create(
      { given, family, birth_date: birthDate, identifiers: [{ system: 'https://bp.example/user', value: userId }] },
      { author_type: 'patient' },
    );
    users.set(userId, { id: userId, email, patientId: patient.id });
    res.status(201).json({ userId });
  } catch (e) { next(e); }
});
```

Anpheros से प्रतिक्रिया नया मरीज़ है, जिसमें एक `id` है जो आपके प्रोजेक्ट से संबंधित है और उसका FHIR संदर्भ है:

```json
{"id": "27296656-c2ba-4970-8424-1dcd91163e0a", "given": "Ioana", "family": "Marin", "birth_date": "1979-04-12", "gender": "female",
 "identifiers": [{"system": "https://bp.example/user", "value": "u_8f2c"}], "updated_at": "2026-10-12T20:16:51.143Z",
 "fhir": "Patient/27296656-c2ba-4970-8424-1dcd91163e0a"}
```

## चरण 3: एक रीडिंग स्टोर करें

ऐप `{systolic, diastolic, measuredAt}` भेजता है। आपका API इसे मान्य करता है और एक रक्तचाप अवलोकन, LOINC `85354-9`, को उसके दो घटकों के साथ स्टोर करता है:

```ts
app.post('/readings', express.json(), async (req, res, next) => {
  try {
    const user = currentUser(req);
    const { systolic, diastolic, measuredAt } = req.body;
    if (![systolic, diastolic].every((v) => Number.isFinite(v) && v > 20 && v < 300)) {
      throw new HttpError(400, 'systolic and diastolic must be numbers in mmHg');
    }
    const obs = await anpheros.observations.create(user.patientId, {
      code: '85354-9',
      category: 'vital-signs',
      effective_at: measuredAt ?? new Date().toISOString(),
      components: [
        { code: '8480-6', value: systolic, unit: 'mm[Hg]' },
        { code: '8462-4', value: diastolic, unit: 'mm[Hg]' },
      ],
      author_type: 'patient',
    }, { source_system: 'bp-app' });
    res.status(201).json({ id: obs.id, measuredAt: obs.effective_at });
  } catch (e) { next(e); }
});
```

Anpheros क्या स्टोर करता है और क्या लौटाता है:

```json
{"id": "78188270-e65e-49bd-89d0-e776226e9614", "patient": "27296656-…", "code": "85354-9", "system": "http://loinc.org",
 "display": "Blood pressure panel", "category": "vital-signs", "effective_at": "2026-10-10T08:30:00Z",
 "components": [{"code": "8480-6", "system": "http://loinc.org", "value": 138.0, "unit": "mm[Hg]"},
                {"code": "8462-4", "system": "http://loinc.org", "value": 88.0, "unit": "mm[Hg]"}],
 "status": "final", "updated_at": "2026-10-12T20:16:51.153Z", "fhir": "Observation/78188270-…"}
```

SDK हर क्रिएट के साथ एक `Idempotency-Key` भेजता है, इसलिए नेटवर्क त्रुटि के बाद पुनः प्रयास करने पर रीडिंग दो बार स्टोर नहीं होती है। `author_type: 'patient'` और `source_system` रीडिंग की उत्पत्ति में जाते हैं: एक डॉक्टर, कोई अन्य ऐप या AI मॉडल बाद में यह बता सकता है कि व्यक्ति ने इसे अपने ऐप से घर पर मापा था।

## चरण 4: रीडिंग वापस पढ़ें

```ts
app.get('/readings', async (req, res, next) => {
  try {
    const user = currentUser(req);
    const page = await anpheros.observations.list(user.patientId, {
      code: '85354-9',
      from: typeof req.query.from === 'string' ? req.query.from : undefined,
      limit: 50,
    });
    res.json({
      readings: page.data.map((o) => ({
        id: o.id,
        measuredAt: o.effective_at,
        systolic: o.components.find((c) => c.code === '8480-6')?.value,
        diastolic: o.components.find((c) => c.code === '8462-4')?.value,
      })),
      next: page.next_cursor,
    });
  } catch (e) { next(e); }
});
```

आपका API उस आकार को लौटाता है जो आपका ऐप चाहता है। संग्रहीत डेटा मानक बना रहता है। क्योंकि उपयोगकर्ता आईडी `currentUser` द्वारा जाँची जाती है, एक उपयोगकर्ता कभी भी दूसरे उपयोगकर्ता की रोगी आईडी नहीं मांग सकता है।

## चरण 5: त्रुटियाँ

Anpheros त्रुटियाँ `AnpherosError` के रूप में आती हैं जिनमें `status`, `type`, `message`, `field` और एक `requestId` होता है। सत्यापन त्रुटियों को ऐप में पास करें और बाकी को छिपा दें:

```ts
app.use((err: unknown, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
  if (err instanceof HttpError) return res.status(err.status).json({ error: err.message });
  if (err instanceof AnpherosError && err.status === 400) {
    return res.status(400).json({ error: err.message, field: err.field });
  }
  console.error(err instanceof AnpherosError ? `anpheros ${err.status} ${err.type} request=${err.requestId}` : err);
  res.status(502).json({ error: 'medical record service unavailable, try again' });
});
```

उदाहरण के लिए, बिना तारीख के एक रीडिंग Anpheros द्वारा `{"error": {"type": "invalid", "message": "Field required (at effective_at)", "field": "effective_at"}}` के साथ अस्वीकार कर दी जाती है। रेट लिमिट (`429`) और सर्वर त्रुटियों को SDK द्वारा पुनः प्रयास किया जाता है इससे पहले कि आप उन्हें देखें। `requestId` को लॉग करें और यदि आप सहायता से संपर्क करते हैं तो इसका उल्लेख करें। पूरी सूची [त्रुटियाँ](https://developers.anpheros.com/hi/guides/errors) में है।

## चरण 6: वेबहुक के साथ नए डेटा के बारे में सुनें

रीडिंग कहीं और से भी आ सकती हैं: एक क्लिनिक जो उसी रिकॉर्ड में लिख रहा है, एक लैब रिपोर्ट, या व्यक्ति द्वारा कनेक्ट किया गया कोई अन्य ऐप। एक बार एक एंडपॉइंट रजिस्टर करें:

```bash
curl -X POST https://platform.anpheros.com/v1/webhooks -H "Authorization: Bearer $ANPHEROS_KEY" \
     -H "Content-Type: application/json" \
     -d '{"url": "https://bp.example/webhooks/anpheros", "events": ["resource.created", "consent.revoked"]}'
```

प्रतिक्रिया में एक `secret` (`whsec_…`) होता है, जो एक बार दिखाया जाता है। उस पर भरोसा करने से पहले हर डिलीवरी को रॉ बॉडी के विरुद्ध सत्यापित करें:

```ts
app.post('/webhooks/anpheros', express.raw({ type: 'application/json' }), async (req, res) => {
  const ok = await verifyWebhookSignature({
    secret: process.env.ANPHEROS_WEBHOOK_SECRET!,
    header: req.header('anpheros-signature'),
    body: req.body as Buffer,
  });
  if (!ok) return res.status(400).end();
  const event = JSON.parse((req.body as Buffer).toString('utf8'));
  // Events carry ids and versions, not clinical data: fetch what you need, then update caches or notify.
  console.log(event.type, event.data);
  res.status(204).end();
});

app.listen(3000, () => console.log('bp-api on http://localhost:3000'));
```

इवेंट प्रकार `resource.created`, `resource.updated`, `resource.deleted`, `consent.granted`, `consent.revoked`, `document.finalized` और `ping` हैं। डिलीवरी हस्ताक्षरित होती हैं, पुनः प्रयास की जाती हैं और उन्हें फिर से चलाया जा सकता है ([वेबहुक](https://developers.anpheros.com/hi/guides/webhooks))।

## चलाएँ

```bash
npx tsx server.ts
curl -X POST localhost:3000/signup -H 'content-type: application/json' \
     -d '{"email":"ioana@example.com","given":"Ioana","family":"Marin","birthDate":"1979-04-12"}'
# {"userId":"…"}
curl -X POST localhost:3000/readings -H 'content-type: application/json' -H 'x-user-id: <userId>' \
     -d '{"systolic":138,"diastolic":88,"measuredAt":"2026-10-10T08:30:00Z"}'
curl localhost:3000/readings -H 'x-user-id: <userId>'
```

आपके मशीन से कुछ भी बाहर निकलने से पहले, अपने वास्तविक प्रमाणीकरण के साथ `x-user-id` स्टैंड-इन को बदलें।

## आगे बढ़ें

- **जिन लोगों के पास पहले से रिकॉर्ड है।** एक API कुंजी आपके प्रोजेक्ट द्वारा बनाए गए रोगियों तक पहुँचती है। अन्य ऐप्स, क्लीनिक या प्रयोगशालाओं द्वारा एकत्र किए गए व्यक्ति के मौजूदा रिकॉर्ड से कनेक्ट करने के लिए, OAuth और उनकी सहमति का उपयोग करें: [SMART on FHIR के साथ रोगी की सहमति कैसे लागू करें](https://developers.anpheros.com/hi/guides/smart-on-fhir-backend)।
- **जब आपको आवश्यकता हो तो सख्त FHIR।** `anpheros.fhir.search`, `create`, `transaction`, `everything` और `summary` आपको समान आईडी के साथ [FHIR R4 API](https://developers.anpheros.com/hi/guides/store-medical-records-fhir) प्रदान करते हैं।
- **AI सुविधाएँ।** `anpheros.context.build` एक मॉडल के लिए स्रोत-लेबल संदर्भ तैयार करता है: [FHIR बैकएंड के साथ AI स्वास्थ्य सेवा ऐप कैसे बनाएं](https://developers.anpheros.com/hi/guides/build-ai-healthcare-app)।
- **उत्पादन।** उत्पादन कुंजियाँ (`sk_live_…`) हस्ताक्षरित DPA के साथ सत्यापित संगठनों को जारी की जाती हैं; [मूल्य निर्धारण](https://developers.anpheros.com/hi/guides/pricing) और [सीमाएँ और दर सीमाएँ](https://developers.anpheros.com/hi/guides/limits) देखें।

## अक्सर पूछे जाने वाले प्रश्न

### क्या मुझे मेडिकल डेटा के लिए अपना डेटाबेस चाहिए?
मेडिकल डेटा के लिए नहीं। आपका डेटाबेस उपयोगकर्ताओं, सत्रों और उत्पाद सेटिंग्स को रखता है, साथ ही प्रत्येक उपयोगकर्ता के लिए रोगी आईडी भी रखता है। अवलोकन, स्थितियाँ, दवाएँ, दस्तावेज़, उनका इतिहास और उन्हें किसने लिखा है, यह सब FHIR रिकॉर्ड में संग्रहीत होता है।

### क्या मोबाइल ऐप सीधे Anpheros को कॉल कर सकता है?
API कुंजी के साथ, नहीं: कुंजी आपके प्रोजेक्ट के हर रोगी तक पहुँचती है और आपके सर्वर पर रहनी चाहिए। मोबाइल ऐप OAuth टोकन के साथ सीधे Anpheros को कॉल कर सकता है जिसे व्यक्ति ने अपने स्वयं के रिकॉर्ड के लिए प्रदान किया है, जैसा कि [Flutter के साथ एक स्वास्थ्य सेवा ऐप कैसे बनाएं](https://developers.anpheros.com/guides/healthcare-app-flutter) में है।

### यह किस फ्रेमवर्क के साथ काम करता है?
कोई भी। SDK को केवल `fetch` की आवश्यकता है, इसलिए यह Express, Fastify, Hono, NestJS, Next.js रूट हैंडलर, Deno या Bun में चलता है।

## संबंधित

- [हेल्थकेयर एपीआई](https://developers.anpheros.com/hi/guides/healthcare-api): हेल्थकेयर एपीआई में क्या देखना चाहिए, और Anpheros API का संक्षिप्त अवलोकन
- [मेडिकल डेटा एपीआई](https://developers.anpheros.com/hi/guides/medical-data-api): किस तरह का मेडिकल डेटा कहाँ जाता है
- [FHIR R4 का उपयोग करके मेडिकल रिकॉर्ड कैसे स्टोर करें](https://developers.anpheros.com/hi/guides/store-medical-records-fhir)
- [वेबहुक्स](https://developers.anpheros.com/hi/guides/webhooks) और [त्रुटियाँ](https://developers.anpheros.com/hi/guides/errors)
- [मेडिकल ऐप बैकएंड और डेटाबेस](https://developers.anpheros.com/hi/guides/medical-app-backend)
