एक्सेस समय विंडोज

Access Time Windows किसी Partner Member को किसी बाहरी सिस्टम द्वारा दी गई अस्थायी या आवर्ती पहुँच रखने देती हैं। यह पेज access_time_windows और access_time_windows_revision के लिए आधिकारिक प्रोड्यूसर गाइड है।

Access Time Windows अतिरिक्त, केवल-अनुमति देने वाली अनुमतियाँ हैं। एक सक्रिय विंडो पहुँच की अनुमति दे सकती है, लेकिन निष्क्रिय, समाप्त, पुरानी (stale) या मैप न की गई विंडो ऐसी पहुँच से इनकार नहीं करती जिसकी अनुमति कोई नियमित नियम या स्थायी अनुमति पहले से देती है। उपयोगकर्ता अक्षमीकरण, स्पष्ट डोर ब्लॉकिंग, मेंटेनेंस मोड, जियोफ़ेंसिंग, रेट लिमिट और कंट्रोलर की उपलब्धता फिर भी लागू होती हैं।

विशेष अपस्ट्रीम सिस्टमों के लिए इम्प्लीमेंटेशन अलग एडेप्टर होते हैं। उन्हें अपने स्रोत डेटा को इसके फ़ील्ड के अर्थ बदले बिना इस विक्रेता-निरपेक्ष अनुबंध में बदलना होगा।

सदस्य स्नैपशॉट फ़ील्ड

  • access_time_windows array वैकल्पिक

    इस सदस्य और पार्टनर स्रोत के लिए पूर्ण Access Time Window स्नैपशॉट। एक स्नैपशॉट में absolute और weekly विंडो मिश्रित हो सकती हैं। संग्रहीत स्नैपशॉट को अपरिवर्तित रखने के लिए फ़ील्ड को छोड़ दें; इस स्रोत की हर विंडो को रद्द करने के लिए [] भेजें।

  • access_time_windows_revision integer access_time_windows के साथ आवश्यक

    इस सदस्य/स्रोत रिविज़न स्ट्रीम के लिए एक लगातार बढ़ने वाला, गैर-ऋणात्मक, JSON-सुरक्षित पूर्णांक। जब भी access_time_windows मौजूद हो, यह आवश्यक है और 9007199254740991 से अधिक नहीं होना चाहिए।

हर स्नैपशॉट में अधिकतम 50 विंडो स्वीकार की जाती हैं। external_id, scope_key और label में अधिकतम 120 अक्षर स्वीकार किए जाते हैं। निरपेक्ष विंडो अधिकतम 90 दिनों की हो सकती हैं। एक साप्ताहिक दिन में अधिकतम आठ गैर-ओवरलैपिंग ब्लॉक स्वीकार किए जाते हैं। अमान्य डेटा को काटने या अनुमान लगाने के बजाय अस्वीकार कर दिया जाता है।

विंडो के स्वरूप

एक निरपेक्ष विंडो एक सटीक अंतराल की पहचान करती है:

{
  "external_id": "access-4b1782",
  "kind": "absolute",
  "from": 1792053000,
  "to": 1792058400,
  "timezone": "Australia/Perth",
  "scope_key": "after_hours_entry",
  "label": "Temporary site access"
}

आवश्यक फ़ील्ड external_id, kind, from और to हैं। timezone, scope_key और label वैकल्पिक हैं।

एक साप्ताहिक विंडो आवर्ती स्थानीय घड़ी-समय अंतरालों की पहचान करती है, जो वैकल्पिक रूप से UTC क्षणों से सीमित होते हैं:

{
  "external_id": "weekly-early-access",
  "kind": "weekly",
  "timezone": "America/New_York",
  "access_hours": {
    "sun": [],
    "mon": [["06:00", "08:30"]],
    "tue": [["06:00", "08:30"]],
    "wed": [["06:00", "08:30"]],
    "thu": [["06:00", "08:30"]],
    "fri": [["06:00", "08:30"]],
    "sat": []
  },
  "active_from": 1790812800,
  "active_until": 1796083200,
  "scope_key": "main_entry",
  "label": "Weekday early access"
}

आवश्यक फ़ील्ड external_id, kind और access_hours हैं। timezone, active_from, active_until, scope_key और label वैकल्पिक हैं।

पूर्ण मिश्रित अनुरोध

यह अनुरोध सदस्य के पिछले, स्रोत के स्वामित्व वाले स्नैपशॉट को एक निरपेक्ष और एक साप्ताहिक विंडो से बदल देता है:

curl -X POST https://partner-api.performancehub.co/partner/v1/members \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "members": [
      {
        "member_id": "member_11111",
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        "first_name": "John",
        "last_name": "Smith",
        "access_time_windows_revision": 1842,
        "access_time_windows": [
          {
            "external_id": "access-4b1782",
            "kind": "absolute",
            "from": 1792053000,
            "to": 1792058400,
            "timezone": "Australia/Perth",
            "scope_key": "after_hours_entry",
            "label": "Temporary site access"
          },
          {
            "external_id": "weekly-early-access",
            "kind": "weekly",
            "timezone": "America/New_York",
            "access_hours": {
              "sun": [],
              "mon": [["06:00", "08:30"]],
              "tue": [["06:00", "08:30"]],
              "wed": [["06:00", "08:30"]],
              "thu": [["06:00", "08:30"]],
              "fri": [["06:00", "08:30"]],
              "sat": []
            },
            "active_from": 1790812800,
            "active_until": 1796083200,
            "scope_key": "main_entry",
            "label": "Weekday early access"
          }
        ]
      }
    ]
  }'

अपनी कॉन्फ़िगर की गई लिंकिंग विधि के अनुसार facility_id या linking_identifier में से किसी एक का उपयोग करें। दोनों न भेजें।

समय और सीमा संबंधी नियम

from, to, active_from और active_until, UTC क्षणों की पहचान करने वाले JSON पूर्णांक Unix सेकंड हैं:

  • बिना उद्धरण चिह्नों वाला JSON पूर्णांक भेजें। संख्यात्मक स्ट्रिंग, फ़्लोट, RFC 3339 स्ट्रिंग और Unix मिलीसेकंड अस्वीकार कर दिए जाते हैं।
  • हर अंतराल अर्ध-खुला है: [from, to)। पहुँच ठीक from पर शुरू हो सकती है; ठीक to पर यह सक्रिय नहीं रहती।
  • from का मान to से कम होना चाहिए। जब दोनों साप्ताहिक सीमाएँ मौजूद हों, तो active_from का मान active_until से कम होना चाहिए।
  • बिना टाइमज़ोन वाली स्थानीय तारीख/समय से epoch न निकालें। पहले स्रोत समय को UTC क्षण में बदलें, फिर Unix मिलीसेकंड को 1000 से विभाजित करें और सत्यापित करें कि परिणाम पूर्णांक है।

Epoch रूपांतरण

2026-10-15T08:30:00Z का रूपांतरण 1792053000 होता है:

UTC instant                 Unix milliseconds   Unix seconds sent
2026-10-15T08:30:00Z        1792053000000        1792053000

भाषा-निरपेक्ष रूपांतरण:

instant = parse_source_timestamp_with_explicit_zone(source_timestamp)
milliseconds = instant.to_unix_milliseconds()
assert milliseconds modulo 1000 equals 0
seconds = milliseconds / 1000
assert seconds is a JSON-safe nonnegative integer

यदि स्रोत में सेकंड से कम की सटीकता है, तो इंटीग्रेशन परीक्षण से पहले शुरुआत/समाप्ति के लिए एक सोची-समझी राउंडिंग नीति तय करें। कभी भी मिलीसेकंड न भेजें और इकाई का अनुमान लगाने के लिए API पर निर्भर न रहें।

टाइमज़ोन और डेलाइट सेविंग

timezone एक मान्य IANA टाइमज़ोन होना चाहिए, जैसे UTC, Australia/Perth या America/New_York। छोड़े जाने पर यह डिफ़ॉल्ट रूप से UTC होता है।

  • निरपेक्ष विंडो: from और to पहले से ही सटीक UTC क्षणों की पहचान करते हैं। timezone केवल प्रदर्शन और ऑडिट मेटाडेटा है; इसे बदलने से कोई भी क्षण कभी नहीं खिसकता।
  • साप्ताहिक विंडो: timezone उस स्थानीय घड़ी-समय और डेलाइट-सेविंग नियमों को परिभाषित करता है जिनका उपयोग access_hours के मूल्यांकन के लिए किया जाता है। साप्ताहिक ब्लॉक को पहले से UTC में न बदलें।
  • घड़ी आगे होने (spring-forward) के बदलाव के दौरान, वह स्थानीय समय जिसे टाइमज़ोन छोड़ देता है, कभी नहीं आता।
  • घड़ी पीछे होने (fall-back) के बदलाव के दौरान, दोहराए गए स्थानीय समय वाले दोनों वास्तविक क्षण साप्ताहिक ब्लॉक से मेल खाते हैं।
  • active_from और active_until, UTC क्षण ही रहते हैं, भले ही साप्ताहिक विंडो गैर-UTC टाइमज़ोन का उपयोग करे।

access_hours लोअरकेस sun से sat तक का उपयोग करता है। हर मान शून्य-पैडेड, 24-घंटे वाले HH:mm का उपयोग करने वाली [start, end] जोड़ियों का ऐरे है। ब्लॉक खाली नहीं होने चाहिए, क्रम में होने चाहिए और ओवरलैप नहीं होने चाहिए। end अपवर्जी (exclusive) है। कोई ब्लॉक आधी रात को पार नहीं कर सकता; रात भर के स्रोत अंतराल को पहले दिन के देर वाले ब्लॉक और अगले दिन के शुरुआती ब्लॉक में विभाजित करें।

स्थिर ID और स्कोप मैपिंग

external_id किसी तार्किक विंडो के पूरे जीवनकाल के लिए स्थिर और सदस्य स्नैपशॉट के भीतर अद्वितीय होना चाहिए। समय या लेबल बदलने पर भी इसे स्थिर रखें ताकि ऑपरेटर और ऑडिट रिकॉर्ड रिविज़न को आपस में जोड़ सकें। इसे किसी असंबंधित विंडो के लिए दोबारा उपयोग न करें।

scope_key आपका स्थिर तार्किक एक्सेस लक्ष्य है। यह डिफ़ॉल्ट रूप से default होता है। एक सुविधा व्यवस्थापक हर अनुमत कुंजी को Performance Hub के सुविधा-व्यापी, दरवाज़े या पहुँच का दायरा लक्ष्यों से मैप करता है:

Partner scope_key           Performance Hub mapping
default                     Facility's configured default target
main_entry                  Access Scope "Main entrances"
after_hours_entry           Doors approved for after-hours entry

पार्टनर किसी विंडो के भीतर Performance Hub सुविधा, दरवाज़े या पहुँच का दायरा ID नहीं भेजते। अज्ञात, अक्षम या मैप न किया गया scope_key उस विंडो के लिए बंद अवस्था में विफल (fail closed) होता है; यह पहुँच का विस्तार नहीं करता। लॉन्च से पहले मैपिंग पर सहमति बनाएँ और उनका परीक्षण करें।

पूर्ण स्नैपशॉट और रिविज़न

इन दो फ़ील्ड को Member अपसर्ट के भीतर एक अलग से संस्करणित विभाजन मानें:

इनपुटपरिणाम
access_time_windows छोड़ा गयामौजूदा स्नैपशॉट अपरिवर्तित रहता है; किसी रिविज़न की आवश्यकता नहीं है
नए रिविज़न के साथ मौजूदइस सदस्य/स्रोत का पूरा संग्रहीत स्नैपशॉट बदल दिया जाता है
वही रिविज़न और वही सामान्यीकृत पेलोडआइडेम्पोटेंट रीप्ले; स्नैपशॉट में कोई बदलाव नहीं
वही रिविज़न और अलग सामान्यीकृत पेलोडकॉन्फ़्लिक्ट; मिलान करने के बाद नया रिविज़न आवंटित करें
पुराना रिविज़नपुराना (stale) स्नैपशॉट छोड़ दिया जाता है; यह नई स्थिति को ओवरराइट नहीं कर सकता
नए रिविज़न के साथ access_time_windows: []स्रोत के स्वामित्व वाली सभी विंडो को स्पष्ट रूप से रद्द करता है

स्नैपशॉट पूर्ण होता है, पैच नहीं। यदि रिविज़न 1842 में विंडो A और B हैं, तो केवल B वाला रिविज़न 1843, A को हटा देता है।

वेबहुक वर्कर्स, पोलिंग, रीप्ले और पूर्ण रिकंसिलिएशन में हर पार्टनर/सदस्य के लिए एक समन्वित रिविज़न स्ट्रीम बनाए रखें। एक टिकाऊ डेटाबेस सीक्वेंस बेहतर है। Unix-मिलीसेकंड मान का उपयोग रिविज़न के रूप में केवल तब किया जा सकता है जब हर लेखक समन्वय करता हो और सख्त क्रम और अद्वितीयता की गारंटी देता हो; यह एक रिविज़न मान है, epoch फ़ील्ड नहीं।

API रिस्पॉन्स ज्ञात होने तक सटीक अनुरोध और रिविज़न को सहेजे रखें। टाइमआउट या अस्थायी त्रुटि के बाद उसी सामान्यीकृत स्नैपशॉट को उसी रिविज़न के साथ पुनः प्रयास करें। केवल इसलिए नया रिविज़न आवंटित न करें कि ट्रांसपोर्ट डिलीवरी अनिश्चित है।

रद्दीकरण, समाप्ति और अपस्ट्रीम विफलताएँ

  • एक विंडो रद्द करें: आधिकारिक स्रोत स्थिति को सफलतापूर्वक फ़ेच करें, उस विंडो को हटाएँ, और शेष पूर्ण स्नैपशॉट को नए रिविज़न के साथ भेजें।
  • सभी विंडो रद्द करें: नए रिविज़न के साथ access_time_windows: [] भेजें।
  • किसी निरपेक्ष विंडो को समाप्त होने दें: यह to पर अनुमति देना बंद कर देती है; स्नैपशॉट को साफ़ रखने के लिए बाद में समाप्त प्रविष्टि के बिना एक रिकंसिलिएशन भेजें।
  • किसी साप्ताहिक विंडो को समाप्त करें: इसे नए स्नैपशॉट में हटा दें, या जब स्रोत में समाप्ति का ज्ञात क्षण हो, तो active_until का उपयोग करें।
  • स्रोत फ़ेच विफल या अधूरा है: [] न भेजें और आंशिक स्नैपशॉट प्रकाशित न करें। अलर्ट करें और फ़ेच को पुनः प्रयास करें। किसी अपस्ट्रीम विफलता को खाली स्नैपशॉट में बदलना अनपेक्षित रूप से पहुँच को रद्द करना है।
  • Partner API अनुरोध सत्यापन में विफल होता है: डेटा ठीक करें और नया रिविज़न केवल तब भेजें जब सामान्यीकृत स्नैपशॉट बदलता है। अस्थायी विफलताओं को मूल रिविज़न के साथ पुनः प्रयास करें।

स्रोत की ताज़गी हर इंटीग्रेशन के लिए उसकी वादा की गई डिलीवरी और रिकंसिलिएशन आवृत्ति के आधार पर कॉन्फ़िगर की जाती है। सक्रिय करने से पहले, स्रोत की अधिकतम आयु, इसके पार होने पर क्या होता है, अलर्ट सीमाएँ, और क्या ऑपरेटर केवल हर विंडो की अपनी सीमाओं पर निर्भर रहने को स्वीकार कर सकते हैं, इन पर सहमति बनाएँ। पुरानी (stale) स्रोत विंडो कभी भी इनकार का नियम नहीं बनती; नियमित नियम और स्थायी अनुमतियाँ फ़ॉलबैक पथ बने रहते हैं।

प्रोड्यूसर एल्गोरिदम

हर सदस्य अपडेट के लिए इस भाषा-निरपेक्ष वर्कफ़्लो का उपयोग करें:

function publish_member(member_key):
    source_result = fetch_authoritative_access_state(member_key)

    if source_result.failed or source_result.incomplete:
        record_failure(member_key)
        schedule_retry(member_key)
        return without sending access_time_windows

    windows = []
    for source_window in source_result.current_windows:
        if source_window.is_absolute:
            windows.append({
                external_id: stable_window_id(source_window),
                kind: "absolute",
                from: to_integer_unix_seconds(source_window.start_instant),
                to: to_integer_unix_seconds(source_window.end_instant),
                timezone: source_window.display_timezone or "UTC",
                scope_key: stable_scope_key(source_window) or "default",
                label: safe_label(source_window)
            })
        else:
            windows.append({
                external_id: stable_window_id(source_window),
                kind: "weekly",
                timezone: valid_iana_zone(source_window.timezone) or "UTC",
                access_hours: split_validate_and_sort_weekly_blocks(source_window),
                active_from: optional_integer_unix_seconds(source_window.active_start),
                active_until: optional_integer_unix_seconds(source_window.active_end),
                scope_key: stable_scope_key(source_window) or "default",
                label: safe_label(source_window)
            })

    normalized_snapshot = validate_sort_and_deduplicate(windows)
    revision = next_durable_member_revision(member_key)
    request = member_upsert_with(normalized_snapshot, revision)
    persist_for_retry(member_key, request)

    response = post_request(request)
    if response.is_transient_or_unknown:
        retry_exact_request_with_same_revision(request)
    else if response.is_revision_conflict:
        reconcile_with_latest_committed_source_state(member_key)
    else if response.is_stale_skip:
        stop_replaying_this_revision_and_reconcile(member_key)

प्रमाणन चेकलिस्ट

अंतिम scope_key मैपिंग का उपयोग करते हुए किसी स्टेज सुविधा में ये जाँच पूरी करें:

  • छोड़े गए टाइमज़ोन वाली निरपेक्ष विंडो स्वीकार की जाती है और उसका मूल्यांकन UTC के रूप में होता है।
  • कस्टम-IANA निरपेक्ष विंडो समान from/to क्षणों को बनाए रखती है।
  • साप्ताहिक कस्टम-IANA विंडो, घड़ी आगे और पीछे होने के बदलावों में स्थानीय घड़ी-समय का पालन करती है।
  • मिश्रित निरपेक्ष/साप्ताहिक स्नैपशॉट पिछले स्नैपशॉट को पूरी तरह बदल देता है।
  • पहुँच ठीक from पर शुरू होती है और ठीक to पर रुकती है; साप्ताहिक ब्लॉक की समाप्ति भी अपवर्जी है।
  • नए रिविज़न के साथ उसी external_id के अंतर्गत समय अपडेट करना प्रभावी होता है।
  • access_time_windows छोड़ने से विंडो बदले बिना अन्य Member फ़ील्ड बदलते हैं।
  • उसी रिविज़न/पेलोड को दोबारा भेजना आइडेम्पोटेंट है।
  • वही रिविज़न/अलग पेलोड कॉन्फ़्लिक्ट लौटाता है और स्नैपशॉट नहीं बदलता।
  • क्रम से बाहर आया पुराना रिविज़न stale के रूप में रिपोर्ट होता है और स्थिति को पीछे नहीं ले जा सकता।
  • नया [] स्रोत के स्वामित्व वाली विंडो को रद्द करता है; अपस्ट्रीम फ़ेच विफल होने पर कुछ भी नहीं भेजा जाता।
  • अज्ञात या मैप न किया गया scope_key बंद अवस्था में विफल होता है और ऑपरेटर को दिखने वाली चेतावनी बनाता है।
  • स्रोत-आयु अलर्ट और कॉन्फ़िगर की गई पुराने-स्रोत की नीति तय सीमा पर काम करती हैं।
  • वेबहुक और पूर्ण रिकंसिलिएशन पथ समान स्नैपशॉट और रिविज़न क्रम पर पहुँचते हैं।
  • स्ट्रीम डिलीवरी तय लक्ष्य के भीतर Door & Gate Access तक पहुँचती है।
  • सक्रिय विंडो मैप किए गए भौतिक दरवाज़े की अनुमति दे सकती है, लेकिन उपयोगकर्ता अक्षमीकरण, blockAllAccess, मेंटेनेंस या जियोफ़ेंसिंग को बायपास नहीं कर सकती।
  • विंडो से पहले, उसके बाहर और उसके बाद, नियमित नियम और स्थायी अनुमतियाँ अन्यथा योग्य उपयोगकर्ताओं को अब भी अनुमति देते हैं।

न्यूनतम टेस्ट वेक्टर

[
  {
    "name": "absolute-half-open",
    "window": {
      "external_id": "tv-absolute",
      "kind": "absolute",
      "from": 1792053000,
      "to": 1792058400
    },
    "expect": {
      "1792052999": "inactive",
      "1792053000": "active",
      "1792058399": "active",
      "1792058400": "inactive"
    }
  },
  {
    "name": "weekly-dst",
    "window": {
      "external_id": "tv-weekly-dst",
      "kind": "weekly",
      "timezone": "America/New_York",
      "access_hours": {
        "sun": [["01:00", "03:30"]],
        "mon": [],
        "tue": [],
        "wed": [],
        "thu": [],
        "fri": [],
        "sat": []
      }
    },
    "expect": "Evaluate local wall time: skipped times do not occur; both repeated 01:30 instants qualify."
  }
]

Unix मिलीसेकंड, संख्यात्मक स्ट्रिंग, फ़्लोट, अमान्य IANA ज़ोन, from >= to, डुप्लिकेट external_id, ओवरलैप होते ब्लॉक, रात भर के ब्लॉक, एक दिन में आठ से अधिक ब्लॉक, 50 से अधिक विंडो और मैप न की गई स्कोप कुंजियों के लिए नकारात्मक वेक्टर भी सबमिट करें।