वित्तीय सिस्टम बनाने के लिए इंजीनियरिंग सिद्धांत
(substack.wasteman.codes)- लेखांकन पिछले कई सौ वर्षों में बहुत ज़्यादा नहीं बदला है
- इसके बावजूद, वित्तीय सिस्टम के लिए software बनाने के सही तरीके को लेकर काफ़ी भ्रम है
- यह लेख बड़े उद्यमों में वित्तीय सिस्टम बनाने के अनुभव से सीखे गए सबक साझा करता है
- फोकस लेखांकन सिस्टम बनाने पर है, लेकिन ये सिद्धांत अधिक सामान्य वित्तीय सिस्टम पर भी लागू होते हैं
बुनियादी वित्तीय शब्दों की परिभाषाएँ
- General Ledger (GL): किसी निश्चित अवधि के दौरान सभी वित्तीय लेनदेन का सार प्रस्तुत करने वाला कंपनी का मुख्य लेखा रिकॉर्ड। इसे संबंधित sub-ledger के aggregate के रूप में समझा जा सकता है
- Sub-ledger: किसी विशेष GL से संबंधित सभी व्यक्तिगत लेनदेन का विस्तृत विवरण शामिल करता है। Sub-ledger के रिकॉर्ड में General Ledger की तुलना में कहीं अधिक granular data होता है (उदाहरण: कोई विशिष्ट ग्राहक, किसी order की कोई विशेष item आदि)। Sub-ledger और GL के बीच data का अंतर business के प्रकार और संसाधित data की मात्रा पर निर्भर करता है। कुछ छोटे business बिना sub-ledger के भी चल सकते हैं, लेकिन ऐसे छोटे पैमाने पर custom software की ज़रूरत पड़ने की संभावना कम होती है
- Financial Record: General Ledger और Sub-ledger के लिए सामूहिक शब्द
- Materiality: यह दर्शाता है कि वित्तीय विवरणों में जानकारी की विकृति किसी समझदार stakeholder के decision-making को प्रभावित करती है या नहीं। यह परिभाषा जानबूझकर थोड़ी अस्पष्ट है, क्योंकि अलग-अलग कंपनियों के materiality threshold अलग होते हैं। उदाहरण के लिए, जिस बात का महत्व सालाना $250k revenue कमाने वाली कंपनी के लिए है, वही सालाना $1B revenue कमाने वाली कंपनी के लिए महत्वहीन हो सकती है। डिज़ाइन के नज़रिए से इस अवधारणा का मुख्य मूल्य वित्तीय data की विभिन्न श्रेणियों का वर्गीकरण करना है
High Level Data Flow
Business System --(Financial Events)--> Sub Ledger(s) --(Summarized Accounting Entries)--> General Ledger
लेखांकन सिस्टम के तीन मुख्य लक्ष्य
- सटीकता (Accurate): वित्तीय रिकॉर्ड को business की ज्ञात स्थिति को दर्शाना चाहिए
- उदाहरण: अगर $9.99 के 10 products बेचे गए, तो संबंधित वित्तीय रिकॉर्ड का कुल $99.90 होना चाहिए
- यह स्पष्ट लग सकता है, लेकिन जब हज़ारों या लाखों लेनदेन को aggregate किया जाता है, तो systems के बीच साधारण summation या rounding errors से गंभीर अशुद्धियाँ पैदा हो सकती हैं
-
Wasteman की टिप्पणी
- लोग कहते हैं कि naming computer science की सबसे कठिन समस्या है, लेकिन मेरे हिसाब से addition उसके ठीक बाद आती है
- पिछले कुछ वर्षों में बड़े पैमाने के वित्तीय systems पर काम करते हुए मैंने अनगिनत बार देखा है कि बहुत छोटे bugs ने data में बहुत बड़ा अंतर पैदा किया
- float पर sums की बात ही मत कीजिए। मैंने मुश्किल तरीके से सीखा कि हमेशा integer का इस्तेमाल क्यों करना चाहिए
- वित्तीय रिकॉर्ड पूर्ण (complete) भी होने चाहिए
- अधिक स्पष्ट रूप से, sub-ledger और General Ledger को किसी निश्चित समय पर हुई सभी business activities का पूरा प्रतिनिधित्व करना चाहिए
- अगर कोई event हुआ लेकिन वह वित्तीय रिकॉर्ड में नहीं है, तो system पूर्ण नहीं है
- इसका मतलब यह नहीं है कि eventual consistency की अनुमति नहीं है
- आपको यह पता होना चाहिए कि data कब complete होगा, ताकि stakeholders को बताया जा सके कि data final हो चुका है
-
Wasteman की टिप्पणी
- completeness सुनिश्चित करना भी आश्चर्यजनक रूप से कठिन समस्या है
- जैसे-जैसे system scale होता है, data कई systems से गुज़रते हुए गलती से बदल सकता है या छूट सकता है
- ऑडिट योग्य (Auditable): वित्तीय रिकॉर्ड का audit करना आसान होना चाहिए ताकि stakeholders errors पकड़ सकें और business performance को सही ढंग से माप सकें
- समयबद्धता (Timely): लेखांकन system को business की विशिष्ट ज़रूरतों को पूरा करना चाहिए
- छोटे business के लिए महीने के अंत में सारे numbers dump करना काफ़ी हो सकता है, लेकिन बड़े business आम तौर पर near real-time system चाहते हैं
- इससे पूरे महीने वित्तीय स्थिति पर नज़र रखना, वित्तीय data के आधार पर तेज़ decision लेना, और month/quarter की शुरुआत में close करने की हड़बड़ी कम करना संभव होता है
- ज़रूरत जो भी हो, हमारा accounting system business की requirements को पूरा करना चाहिए, और उनके लिए timely का जो मतलब है वही देना चाहिए
-
Wasteman की टिप्पणी
- लोग timely के संदर्भ में batch बनाम streaming systems की चर्चा में अक्सर भटक जाते हैं
- मेरी राय में ज़्यादातर systems में यह कोई महत्वपूर्ण distinction नहीं है
- अगर आपको seconds से minutes तक की बहुत कम latency की चिंता है, तभी यह मायने रखता है
- लेकिन यह आश्चर्यजनक रूप से आम है कि जब consumer को दिन में कुछ बार से ज़्यादा updates देखने की ज़रूरत नहीं होती, तब भी लोग किस approach का इस्तेमाल हो इस पर बहस करते रहते हैं
- सिर्फ़ इसलिए कि किसी ने माँगा है, इसका मतलब यह नहीं कि उसकी वास्तव में ज़रूरत भी है
लेखांकन सिस्टम के लिए तीन मुख्य इंजीनियरिंग सिद्धांत
- Data की Immutability और Durability
- यह auditability संभव बनाती है, जिससे debugging और accuracy में मदद मिलती है
- जब data immutable होता है, तो किसी भी समय system की state को रिकॉर्ड किया जा सकता है
- इससे किसी पिछली state से दुनिया की दोबारा गणना करना बहुत आसान हो जाता है, क्योंकि कोई state खोती नहीं है
- एक बार वित्तीय रिकॉर्ड में लिखे गए data को delete नहीं किया जा सकता
- system में हर correction को नए वित्तीय लेनदेन के रूप में दिखाया जाना चाहिए
- उदाहरण: अगर system में bug था और $900 की service गलती से $1000 में बेची गई दिखी
- इस गलती को ठीक करने के लिए पहले उस गलती वाले accounting entry को reverse करना चाहिए और फिर सही राशि के साथ accounting entry दोबारा दर्ज करनी चाहिए
- Data को सबसे छोटे grain पर रिकॉर्ड किया जाना चाहिए
- ऊपर वाले सिद्धांत की तरह, यह भी साफ़ audit trail सक्षम करने के लिए बहुत महत्वपूर्ण है
- भले ही वित्तीय reports और General Ledger aggregate हों, वे अधिक granular events से calculate किए जाते हैं
- जब data समझ में नहीं आता, तो यह debug करने के लिए कि समस्या क्या थी, सबसे granular data की ज़रूरत होती है
- data को सबसे निचले स्तर की granularity पर store करने से उसी dataset से निकले derived data को ठीक करना भी बहुत आसान हो जाता है
- अगर एक immutable dataset उस data के सभी views के लिए truth का core source है,
- तो views को ठीक करने के लिए बस data को सुधारें और फिर वे views बनाने वाली pipeline को दोबारा चला दें
- इसी तरह जब accountants books close करने के लिए तैयार होते हैं,
- वे books की accuracy verify करने के लिए हुई सभी transactions और account balances का reconciliation करते हैं
- अगर mismatch मिलता है, तो वे ठीक उसी transaction तक जा सकते हैं जो समस्या पैदा कर रही है
- Idempotency होनी चाहिए
- हर वित्तीय event को केवल एक बार process किया जाना चाहिए, और वित्तीय रिकॉर्ड में duplication स्पष्ट अशुद्धि पैदा करेगा
- इसी कारण वित्तीय रिकॉर्ड बनाने वाला हर code path idempotent होना चाहिए
- idempotent का मतलब है कि किसी operation को कई बार लागू करने पर भी result नहीं बदलता
- यानी, वित्तीय event को कई बार process करने पर भी परिणाम पहली processing जैसा ही रहना चाहिए
Best practices
- वित्तीय राशियों को दर्शाने के लिए integer को प्राथमिकता दें: arithmetic operations बहुत आसान हो जाते हैं। float से बचें
- currency conversion के समय precision loss को कम करने के लिए वित्तीय राशियों की पर्याप्त granularity support करें
- अगर आप सिर्फ़ dollar से काम करते हैं, तो cent unit में value दिखाना पर्याप्त हो सकता है
- global business के लिए micro units या
DECIMAL(19, 4)जैसे decimals को प्राथमिकता दें - वित्तीय systems में decimal चुनना लोकप्रिय है, लेकिन ad finance systems में micro standard है
- consistent rounding method का उपयोग करें: rounding का तरीका अपेक्षित राशि से महत्वपूर्ण अंतर पैदा कर सकता है
- जैसे 5 या उससे ऊपर को अगले significant digit तक round करना, और 4 या उससे नीचे को round down करना
- या हमेशा round up करना
- महत्वपूर्ण बात यह है कि पूरे system में consistency बनी रहे (अगर हर transaction पर 1 cent का अंतर हो, तो 10 million transactions पर $100k का फर्क पड़ता है)
- जहाँ तक संभव हो currency conversion को टालें: बहुत जल्दी currency convert करने से precision loss हो सकता है
- local currency में aggregation होने के बाद तक conversion को delay करें
- समय का integer representation इस्तेमाल करें: यह थोड़ा विवादास्पद हो सकता है, लेकिन मज़बूत सिफ़ारिश है
- timestamps को object के रूप में parse करने वाली अलग-अलग libraries उन्हें अलग तरह से handle करती हैं
- इन झंझटों से बचने और integer इस्तेमाल करने की सलाह दी जाती है
- Unix timestamp या UTC-आधारित integer datetime भी पूरी तरह काम करते हैं
- systems के बीच data transformation जितना कम हो, उतना अच्छा
-
Wasteman की टिप्पणी
- daylight saving time से जुड़े bugs का तो मैंने ज़िक्र भी नहीं किया। बढ़ते हुए integers इस्तेमाल करने से इन्हें पूरी तरह टाला जा सकता है
- अगर आप datetime पर ज़ोर देते हैं, तो कम से कम UTC का उपयोग करें। यह हैरान करने वाली बात है कि बहुत बड़ी कंपनियाँ भी non-UTC timestamps का उपयोग करती हैं
2 टिप्पणियां
यह वाकई बहुत उपयोगी है। अगर बिना ठीक से सोचे type conversion (
decimal,float,double) या rounding को वास्तविक कामकाजी चर्चा के बिना ही कर दिया जाए, तो बड़ा नुकसान हो सकता है।Hacker News टिप्पणियाँ
एकसमान rounding methodology इस्तेमाल करने के महत्व पर ज़ोर
समय को integer के रूप में दर्शाने की विधि की सिफारिश
अकाउंटिंग सिस्टम में relational database इस्तेमाल करने की सिफारिश
अकाउंटिंग सिस्टम के प्रमुख लक्ष्य accuracy, auditability और timeliness हैं
अकाउंटिंग सिस्टम की completeness पर राय
global business के लिए कम से कम 8 decimal places इस्तेमाल करने की सिफारिश
user interface(UI) के महत्व का उल्लेख
batch processing और streaming processing के अंतर की व्याख्या
TypeScript का उपयोग करके invoice system बनाने का अनुभव साझा
standard library की classes इस्तेमाल करने की सिफारिश
rounding और data sharing की कठिनाइयों की व्याख्या
अमेरिका के शीर्ष 10 बैंकों में से एक के API पर काम करने का अनुभव साझा
Martin Fowler की "Accounting Patterns" की सिफारिश